API Reference
All TARS API endpoints, request/response schemas, authentication headers, and error codes.
/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.
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 |
|---|---|
| 400 | Bad request — invalid JSON or missing required field |
| 401 | Unauthorized — missing or invalid authentication credential |
| 404 | Resource not found |
| 405 | Method not allowed |
| 500 | Internal 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/
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
| Field | Type | Description |
|---|---|---|
| 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/
Return a paginated list of tasks for the authenticated user, newest first by default. Used by the chat feed for infinite scroll.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| 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/
Register a new worker. Returns an API key that must be passed with all subsequent worker requests.
Request Body
| Field | Type | Description |
|---|---|---|
| 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/
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)
| Field | Type | Description |
|---|---|---|
| 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/
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/
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
| Field | Type | Description |
|---|---|---|
| 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/
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.