API Reference
REST API endpoints for Sesame
Sesame provides a REST API for programmatic access to all features. The API is built with Hono and runs on port 13531.
Base URL
http://localhost:13531/apiIf you're accessing remotely, use your deployment URL:
https://your-domain.com/apiAuthentication
Create API keys in the UI at Settings > API Keys. API keys have the prefix sk_ and can be passed via:
X-API-Key header:
curl -H "X-API-Key: sk_..." \
http://localhost:13531/api/tasksAuthorization header:
curl -H "Authorization: Bearer sk_..." \
http://localhost:13531/api/tasksAPI keys support:
- Expiration: Set expiration time when creating the key
- Rate limiting: 100 requests per minute per key
- Permissions: Default permissions for tasks (read/write), repos (read), and settings (read)
Endpoints
Health
GET /api/health
Check server health status.
Response:
{
"status": "healthy",
"timestamp": "2024-01-15T10:30:00.000Z"
}Tasks
GET /api/tasks
List all tasks for the authenticated user.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
status | string | Filter by status: pending, processing, completed, failed |
limit | number | Max results (default: 50) |
offset | number | Pagination offset |
Response:
{
"tasks": [
{
"id": "task_abc123",
"title": "Add authentication",
"status": "completed",
"agent": "claude-code",
"repository": "owner/repo",
"branch": "sesame/task-abc123",
"createdAt": "2024-01-15T10:00:00.000Z",
"completedAt": "2024-01-15T10:15:00.000Z"
}
],
"total": 42
}POST /api/tasks
Create a new task.
Request Body:
{
"prompt": "Add user authentication with JWT",
"repository": "owner/repo",
"agent": "claude-code",
"branch": "main"
}Response:
{
"id": "task_abc123",
"status": "pending"
}GET /api/tasks/:taskId
Get details for a specific task.
Response:
{
"id": "task_abc123",
"title": "Add authentication",
"prompt": "Add user authentication with JWT",
"status": "processing",
"agent": "claude-code",
"repository": "owner/repo",
"branch": "sesame/task-abc123",
"messages": [
{
"role": "assistant",
"content": "I'll add JWT authentication...",
"timestamp": "2024-01-15T10:05:00.000Z"
}
],
"createdAt": "2024-01-15T10:00:00.000Z"
}GET /api/tasks/:taskId/stream
Stream task output via Server-Sent Events (SSE).
Headers:
| Header | Description |
|---|---|
Last-Event-ID | Resume from a specific event sequence number. On reconnection, the server replays all events after this seq value. |
Response: SSE stream using a unified event type. All events are UniversalEvent objects distinguished by their kind field:
| Kind | Description |
|---|---|
message | Text output from the agent (textDelta, fullText) |
tool_call | Agent invoking a tool (includes toolCall object) |
tool_result | Result of a tool invocation |
thinking | Agent's internal reasoning (thinkingText) |
permission_request | Agent requesting permission for a tool call |
permission_response | User's decision on a permission request |
status | Task status and progress updates |
error | Error during execution |
log | Log entries from task execution (logType, logMessage) |
done | Task completed (terminal state reached) |
ping | Keepalive signal (every 30 seconds) |
Every event includes a monotonic seq ID used as the SSE id: field for replay support.
id: 0
event: event
data: {"seq":0,"kind":"status","timestamp":"2025-01-15T10:00:00.000Z","status":"processing","progress":0}
id: 1
event: event
data: {"seq":1,"kind":"log","timestamp":"2025-01-15T10:00:01.000Z","logType":"info","logMessage":"Cloning repository..."}
id: 2
event: event
data: {"seq":2,"kind":"message","timestamp":"2025-01-15T10:00:05.000Z","textDelta":"I'll add JWT auth...","fullText":"I'll add JWT auth..."}
id: 3
event: event
data: {"seq":3,"kind":"tool_call","timestamp":"2025-01-15T10:00:06.000Z","toolCall":{"callId":"tc_1","name":"Write","input":{"path":"auth.ts"},"state":"running","description":null,"createdAt":1705312806000,"startedAt":1705312806000,"completedAt":null}}
id: 4
event: event
data: {"seq":4,"kind":"done","timestamp":"2025-01-15T10:00:30.000Z","status":"completed"}
event: ping
data: keepalivePOST /api/tasks/:taskId/cancel
Cancel a running task.
POST /api/tasks/:taskId/retry
Retry a failed task.
Repositories
GET /api/repos
List repositories accessible to the user.
Response:
{
"repositories": [
{
"id": 123456,
"name": "my-project",
"full_name": "owner/my-project",
"private": false,
"default_branch": "main"
}
]
}GET /api/repos/:owner/:repo/branches
List branches for a repository.
GitHub
GET /api/github/pat
Get current GitHub PAT status (not the token itself).
Response:
{
"configured": true,
"username": "octocat",
"scopes": ["repo", "read:user"]
}POST /api/github/pat
Set or update GitHub PAT.
Request Body:
{
"token": "ghp_xxxxxxxxxxxx"
}DELETE /api/github/pat
Remove GitHub PAT.
API Keys
GET /api/api-keys
List configured API keys (names only, not values).
Response:
{
"keys": [
{ "provider": "anthropic", "configured": true },
{ "provider": "openai", "configured": false }
]
}POST /api/api-keys
Set an API key.
Request Body:
{
"provider": "anthropic",
"key": "sk-ant-..."
}DELETE /api/api-keys/:provider
Remove an API key.
Agent Credentials
GET /api/agent-credentials
List configured agent credentials.
POST /api/agent-credentials
Set agent subscription credentials.
Request Body:
{
"agent": "claude-code",
"credentials": {
"oauthToken": "sk-ant-oat01-..."
}
}DELETE /api/agent-credentials/:agent
Remove agent credentials.
Settings
GET /api/settings
Get current settings.
Response:
{
"settings": {
"ai.model": "gpt-4o-mini",
"registration.allowNewUsers": true
},
"locked": ["ai.apiKey"]
}PATCH /api/settings
Update settings (admin only).
Request Body:
{
"ai.model": "claude-3-haiku"
}Admin
GET /api/admin/users
List all users (admin only).
PATCH /api/admin/users/:userId
Update user role (admin only).
DELETE /api/admin/users/:userId
Delete a user (admin only).
GET /api/admin/audit
Get audit logs (admin only).
Setup
GET /api/setup/status
Check if initial setup is complete.
Response:
{
"setupComplete": true,
"hasAdmin": true
}Error Responses
All errors follow the RFC 7807 Problem Details format:
{
"type": "urn:sesame:error:not-found",
"title": "Not Found",
"status": 404,
"detail": "Task not found"
}| Field | Type | Description |
|---|---|---|
type | string | URN identifying the error type (stable, machine-readable) |
title | string | Short human-readable summary |
status | number | HTTP status code |
detail | string | Human-readable explanation of this specific occurrence |
Error type URNs:
| Type | HTTP Status | Description |
|---|---|---|
urn:sesame:error:bad-request | 400 | Invalid request data |
urn:sesame:error:unauthorized | 401 | Not authenticated |
urn:sesame:error:forbidden | 403 | Not authorized for this action |
urn:sesame:error:not-found | 404 | Resource not found |
urn:sesame:error:conflict | 409 | Resource conflict |
urn:sesame:error:unprocessable-entity | 422 | Valid request but cannot process |
urn:sesame:error:internal-error | 500 | Server error |
Rate Limiting
- Authentication endpoints have built-in rate limiting (10 attempts per minute) to prevent brute force attacks.
- General API endpoints do not have application-level rate limiting. For production deployments, configure rate limiting at your reverse proxy (nginx, Caddy, Cloudflare, etc.). See Reverse Proxies for configuration examples.
WebSocket / SSE
Real-time features use Server-Sent Events (SSE) rather than WebSockets:
- Task streaming:
GET /api/tasks/:taskId/stream - Terminal output:
GET /api/tasks/:taskId/terminal/stream
SSE provides simpler proxy configuration and automatic reconnection. The task stream uses monotonic sequence IDs as SSE id: fields, enabling reliable replay via the Last-Event-ID header on reconnection. All task events use a unified UniversalEvent schema — the frontend doesn't need to know which agent provider produced the output.