API & WebSocket reference
Tmates ships a single FastAPI app defined in app/api/main.py. Routers are grouped by feature and all endpoints are prefixed with /v1. Use this guide alongside the autogenerated OpenAPI docs available at /docs or /redoc on any deployment.
Authentication
- Header:
Authorization: Bearer <Supabase JWT> - JWTs come from the same Supabase project that backs your workspace. Tmates Mobile and the Tmates CLI automatically refresh them; external integrations must handle refresh themselves.
- WebSocket connections pass the token via the
tokenquery parameter (see Using Tmates for client workflows).
Router quick reference
| Router | Key endpoints | Purpose |
|---|---|---|
agents (app/api/routes/agents.py) | GET /agents/store, POST /agents/hire, POST /agents/dismiss | Manage tmates installed for an org. |
agent_catalog | GET /agent-catalog, POST /agent-catalog/sync | Admin/catalog operations when curated bundles are enabled. |
chats | GET /chats, POST /chats/{thread_id}/messages, POST /chats | Create/list threads and send messages. |
files | GET /files, POST /files/upload, GET /files/download/{path} | User uploads and downloads. |
pinboard | GET /pinboard, POST /pinboard | Long-form updates. |
jobs | GET /jobs/{job_id} | Inspect Celery job status. |
billing | GET /billing/plan, POST /billing/checkout | Stripe billing and plan context. |
settings | GET/PATCH /settings/mobile | Mobile notification preferences. |
profile | GET /profile/me | Basic profile info. |
websocket | /ws/{user_id} | Realtime events for chats and job status. |
Each router uses dependency injection (fastapi.Depends) to pull the authenticated user ID and database client, so every request is scoped to the correct organization automatically.
Example: send a message
curl https://api.tmates.app/v1/chats/team:all/messages \
-H "Authorization: Bearer $SUPABASE_JWT" \
-H "Content-Type: application/json" \
-d '{
"content": "Share the latest pinboard summary",
"attachments": []
}'
Response:
{
"id": "msg_123",
"role": "user",
"content": "Share the latest pinboard summary",
"author": "Alex",
"created_at": "2024-05-12T19:41:02.123Z",
"attachments": []
}
Expect a 202 Accepted + job ID if the request schedules background work; otherwise you’ll receive the delivered message immediately.
Example: WebSocket payloads
// Chat status
{
"type": "chat_status",
"thread_id": "team:all",
"status": "in_progress",
"agent_key": "nolan",
"status_message": "Generating storyboard…",
"job_id": "job_abc"
}
// Final response
{
"type": "new_message",
"thread_id": "team:all",
"payload": {
"id": "msg_xyz",
"role": "assistant",
"author": "Nolan",
"content": "Uploaded the storyboard to Files.",
"attachments": [
{
"name": "storyboard.png",
"relative_path": "users/123/storyboard.png",
"download_url": "/v1/files/download/users/123/storyboard.png"
}
]
}
}
The WebSocket server automatically drops connections when tokens expire or when a client is idle for too long, so reconnect and resubscribe as needed.
Error handling
All endpoints raise FastAPI HTTPExceptions with descriptive messages. Common cases:
401 Unauthorized– missing or expired Supabase token.403 Forbidden– attempting to access a file or thread outside the current org.404 Not Found– unknown thread, tmate key, or pinboard slug.409 Conflict– hiring an already installed tmate.429 Too Many Requests– rate limits in Tmates Cloud (configurable per workspace).
Clients should display these errors verbosely so workspace admins know how to fix the underlying issue (e.g., enable a tmate before messaging it).