Documentation

API Reference

All TARS API endpoints, request/response schemas, authentication headers, and error codes.

For users: task submission is done through the web chat interface — no API key needed. The endpoints on this page are primarily for worker and controller communication. The /api/tasks/ endpoints are also used internally by the dashboard chat UI (session-authenticated).

Authentication

Worker API Key

Worker endpoints require a worker API key passed in the X-Worker-Key HTTP header:

X-Worker-Key: <your-worker-api-key>

Session Authentication

The /api/tasks/ endpoints use Django session authentication (cookie-based). Callers must be logged in. Mutating requests (POST) must also include the CSRF token:

X-CSRFToken: <csrf-token>

Webhook endpoints use signature verification — see the Webhooks section.

All endpoints communicate over HTTPS. HTTP requests are redirected to HTTPS.

Base URL

https://tarsai.dev

Error Responses

All errors return JSON with an error field:

{
  "error": "Invalid or missing X-Worker-Key"
}
Status Code Meaning
400Bad request — invalid JSON or missing required field
401Unauthorized — missing or invalid authentication credential
404Resource not found
405Method not allowed
500Internal server error

Task Endpoints

These endpoints are used by the dashboard chat UI and are protected by Django session authentication. They are not intended for use with a worker API key.

POST /api/tasks/

POST /api/tasks/

Create a new task. This is the endpoint the web chat interface uses when a user submits a request. Requires an active session and CSRF token. Rate-limited to 30 requests per hour per user.

Headers

X-CSRFToken: <csrf-token>
Content-Type: application/json

Request Body

FieldTypeDescription
project_idrequired integer ID of the project to associate the task with. Must be a project the authenticated user has access to.
titlerequired string Short description of what TARS should do. Displayed as the task name.
descriptionoptional string Extended details for TARS. Defaults to the value of title if omitted.

Example Request

curl -s -X POST https://tarsai.dev/api/tasks/ \
  -H "X-CSRFToken: <csrf-token>" \
  -H "Content-Type: application/json" \
  -d '{
    "project_id": 12,
    "title": "Add rate limiting to the login endpoint",
    "description": "Use django-ratelimit; allow 10 attempts per minute per IP."
  }'

Example Response — 201 Created

{
  "id": 1338,
  "title": "Add rate limiting to the login endpoint",
  "description": "Use django-ratelimit; allow 10 attempts per minute per IP.",
  "status": "pending",
  "status_display": "Pending",
  "project": "backend-api",
  "created_at": "2026-04-27T14:32:00.000Z"
}

GET /api/tasks/

GET /api/tasks/

Return a paginated list of tasks for the authenticated user, newest first by default. Used by the chat feed for infinite scroll.

Query Parameters

ParameterTypeDescription
pageoptional integer Page number (1-indexed). Defaults to 1.
per_pageoptional integer Results per page. Defaults to 20; max 100.
statusoptional string Filter by status. One of: pending, queued, assigned, in_progress, reviewing, completed, failed.
projectoptional integer Filter by project ID.
qoptional string Full-text search across title and description.
sortoptional string Sort order. One of created_at (oldest first) or -created_at (newest first, default).

Example Request

curl -s "https://tarsai.dev/api/tasks/?page=1&per_page=20&status=completed"

Example Response — 200 OK

{
  "tasks": [
    {
      "id": 1338,
      "title": "Add rate limiting to the login endpoint",
      "status": "completed",
      "status_display": "Completed",
      "project": "backend-api",
      "branch_name": "tars/rate-limit-login-1338",
      "pr_url": "https://github.com/acme-corp/backend-api/pull/92",
      "error_message": null,
      "created_at": "2026-04-27T14:32:00.000Z",
      "completed_at": "2026-04-27T14:45:00.000Z"
    }
  ],
  "has_more": false,
  "next_page": null
}

POST /api/workers/register/

POST /api/workers/register/

Register a new worker. Returns an API key that must be passed with all subsequent worker requests.

Request Body

FieldTypeDescription
hostnamerequired string Unique identifier for this worker (e.g. machine hostname or a UUID)
capacityoptional integer Maximum number of concurrent tasks. Defaults to 1.
specsoptional string Free-form text describing the worker's hardware (e.g. "8-core / 32GB RAM")

Example Request

curl -s -X POST https://tarsai.dev/api/workers/register/ \
  -H "Content-Type: application/json" \
  -d '{
    "hostname": "worker-us-east-01",
    "capacity": 2,
    "specs": "8-core / 16GB RAM"
  }'

Example Response — 201 Created

{
  "worker_id": 42,
  "api_key": "f47ac10b-58cc-4372-a567-0e02b2c3d479"
}

POST /api/workers/heartbeat/

POST /api/workers/heartbeat/

Signal that the worker is still alive. Send this every 15–30 seconds. Workers that miss heartbeats for more than 5 minutes are marked offline.

Headers

X-Worker-Key: <api-key>

Request Body (all optional)

FieldTypeDescription
current_loadoptional integer Number of tasks currently running on this worker
statusoptional string One of online, busy, offline, maintenance

Example Request

curl -s -X POST https://tarsai.dev/api/workers/heartbeat/ \
  -H "X-Worker-Key: f47ac10b-58cc-4372-a567-0e02b2c3d479" \
  -H "Content-Type: application/json" \
  -d '{"current_load": 1, "status": "busy"}'

Example Response — 200 OK

{"ok": true}

GET /api/workers/next-task/

GET /api/workers/next-task/

Claim the next available task from the queue. Returns null if the worker is at capacity or no tasks are pending. Uses an optimistic scoring algorithm that considers task priority, wait time, and project affinity.

Headers

X-Worker-Key: <api-key>

Example Request

curl -s https://tarsai.dev/api/workers/next-task/ \
  -H "X-Worker-Key: f47ac10b-58cc-4372-a567-0e02b2c3d479"

Example Response — task available

{
  "task": {
    "id": 1337,
    "title": "Fix the 500 error on password reset",
    "description": "Occurs when the reset token is expired. Should return 400 with a user-friendly message.",
    "priority": 5,
    "project": {
      "id": 12,
      "name": "backend-api",
      "github_repo": "acme-corp/backend-api",
      "default_branch": "main"
    }
  }
}

Example Response — no task available

{"task": null}

POST /api/workers/task/<id>/update/

POST /api/workers/task/<id>/update/

Update the status or metadata of an assigned task. Called at each stage of execution to report progress. Triggers email notifications and WebSocket broadcasts to the dashboard.

Headers

X-Worker-Key: <api-key>

Request Body

FieldTypeDescription
statusoptional string Task status. One of:
pending · assigned · in_progress · reviewing · completed · failed
branch_nameoptional string Git branch name where the changes are committed
pr_urloptional string Full URL of the GitHub pull request
error_messageoptional string Human-readable error message (when status is failed)

Task Lifecycle

A typical task progresses through these states:

pending → assigned → in_progress → reviewing → completed

On failure at any stage:

pending → assigned → in_progress → failed

Example Request — starting work

curl -s -X POST https://tarsai.dev/api/workers/task/1337/update/ \
  -H "X-Worker-Key: f47ac10b-58cc-4372-a567-0e02b2c3d479" \
  -H "Content-Type: application/json" \
  -d '{"status": "in_progress"}'

Example Request — PR opened

curl -s -X POST https://tarsai.dev/api/workers/task/1337/update/ \
  -H "X-Worker-Key: f47ac10b-58cc-4372-a567-0e02b2c3d479" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "reviewing",
    "branch_name": "tars/fix-password-reset-1337",
    "pr_url": "https://github.com/acme-corp/backend-api/pull/88"
  }'

Example Response — 200 OK

{
  "ok": true,
  "task_id": 1337,
  "status": "reviewing"
}

GET /api/health/

GET /api/health/

Health check endpoint — no authentication required. Returns 200 OK when the server and database are reachable, or 503 Service Unavailable if the database is down.

Example Response — 200 OK

{
  "status": "ok",
  "db": true,
  "redis": true,
  "version": "1.0"
}

Example Response — 503 Service Unavailable

{
  "status": "error",
  "db": false,
  "redis": false,
  "version": "1.0"
}

Webhooks

POST /webhooks/stripe/

Stripe sends payment events to this endpoint. TARS verifies the Stripe-Signature header using your webhook signing secret before processing events.

This endpoint is for Stripe's use only. Do not POST to it directly — all requests without a valid Stripe signature are rejected.