Base URL: http://localhost:3001 (configurable via API_PORT)
All request/response bodies are JSON. Authentication uses Bearer JWT tokens or personal access tokens where noted.
Returns server status and connected SSE client count.
{ "status": "ok", "timestamp": "...", "clients": 2 }GitHub OAuth is the primary login method for human users; Personal Access Tokens (see below) cover MCP/CLI/API clients, and optional TOTP 2FA can be layered on top. After login, all downstream AI provider keys (OpenAI, Anthropic, etc.) are managed by OpenCode itself, not by OpenLinear.
Redirects to GitHub OAuth authorization page.
Handles OAuth callback. Exchanges code for token, creates/updates user, redirects to frontend with JWT.
Auth: required. Returns the authenticated user (excludes the GitHub access token).
Returns { success: true }. Client should clear the stored JWT.
PATs are intended for MCP clients and API integrations. The API stores token hashes and returns the raw token only at creation time.
Auth: required. List PAT metadata for the authenticated user.
Auth: required. Create a PAT.
Body:
{
"name": "MCP client",
"scopes": ["*"],
"expiresAt": "2026-12-31T23:59:59.000Z"
}scopes and expiresAt are optional. When omitted, scopes default to ["*"].
The response includes the raw token once.
Auth: required. Revoke a PAT owned by the authenticated user.
Connect a public repository by URL. No auth required.
Body: { "url": "https://github.com/owner/repo" }
Auth: required. Fetch user's GitHub repos.
Auth: required. Import a GitHub repo.
Body: { "repo": { id, name, full_name, clone_url, default_branch, private, description } }
Auth: required. Set as active repository for the authenticated user.
Auth: required. Get user's active repository.
Auth: required. List user's imported repositories.
List all public (unauthenticated) repositories.
Get the active public repository.
Set a public repository as active.
List non-archived tasks. Optional query params: teamId, projectId.
Create a task.
Body:
{
"title": "Fix login button",
"description": "Optional longer description",
"priority": "high",
"dueDate": "2025-03-15T17:00:00.000Z",
"labelIds": ["uuid-1"],
"teamId": "uuid",
"projectId": "uuid"
}Auth: required. Create up to 100 tasks in one team-backed project. PAT
requests must satisfy the tasks:write scope check.
Body:
{
"projectId": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
"tasks": [
{
"title": "Add MCP docs",
"description": "Document PAT auth and plan creation",
"priority": "medium",
"status": "todo",
"labelIds": ["bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb"],
"parentId": "cccccccc-cccc-4ccc-8ccc-cccccccccccc",
"dueDate": "2026-06-01T12:00:00.000Z"
},
{
"title": "Add MCP smoke test",
"labelIds": ["11111111-1111-4111-8111-111111111111"]
}
]
}The response separates created tasks from per-item failures:
{
"created": [
{
"id": "33333333-3333-4333-8333-333333333333",
"title": "Add MCP docs",
"identifier": "DOC-42"
}
],
"failed": [
{
"index": 1,
"error": "Invalid labelIds: 11111111-1111-4111-8111-111111111111"
}
]
}Invalid label IDs or inaccessible parent IDs fail only those task inputs. Schema validation errors reject the full request.
Get a single task with labels, team, and project.
Update a task. Any field from create, plus status. Setting labelIds replaces all labels.
Archives the task (soft delete). Broadcasts task:deleted.
Auth: optional. Start AI execution. Returns 400 if task is already running or parallel limit reached.
Cancel a running task. Returns 400 if task is not running.
Check if a task is currently executing. Returns { "running": true/false }.
Get execution logs. Returns in-memory logs for active executions, or persisted logs from the database for completed ones.
Auth: optional. Check if a PR exists for a task's compare URL branch and update the link.
List archived tasks.
Permanently delete all archived tasks.
Permanently delete a single archived task.
List all labels ordered by priority (descending).
Create a label. Body: { "name": "bug", "color": "#ff5733", "priority": 0 }
Update a label's name, color, or priority.
Delete a label.
Assign a label to a task. Body: { "labelId": "uuid" }
Remove a label from a task.
Get execution settings. Auto-creates defaults if not present.
Update settings. Body can include any combination of: parallelLimit, maxBatchSize, queueAutoApprove, stopOnFailure, conflictBehavior.
Create and start a batch. Body: { "taskIds": ["uuid-1", ...], "mode": "parallel" | "queue" | "combined" }
List active batches.
Get batch status with per-task progress breakdown.
Cancel entire batch. Aborts running tasks, marks queued tasks cancelled.
Cancel a single task within a batch.
Approve the next queued task in queue mode (when auto-approve is off).
List all teams with member counts.
Auth: optional. Create a team. Creator becomes owner.
Get team with members and project associations.
Auth: optional. Update team.
Auth: optional. Delete team with cascading cleanup.
List team members.
Auth: required. Add a member by email or userId.
Auth: optional. Remove a member.
Auth: required. Join a team using an invite code.
Body: { "inviteCode": "string" }
Response: the team object with members. Errors: 400 (missing code), 404 (invalid code), 409 (already a member).
List all projects with teams and task counts.
Auth: required. Create a project.
Get project with team associations.
Auth: required. Update project.
Auth: required. Delete project (unlinks tasks).
List completed and cancelled (done or cancelled, non-archived) tasks with labels, team, and project.
Get count of unread inbox items.
Mark a single inbox item as read.
Mark all inbox items as read.
SSE endpoint. Optional query param: clientId. See Real-time Events for the full event catalog.
Returns OpenCode system state (whether the sidecar is running and healthy).
Auth: required. List available LLM providers from the user's OpenCode instance.
Auth: required. Get provider authentication status.
Auth: required. Set an API key for a provider.
Body: { "providerId": "anthropic", "apiKey": "sk-..." }
Response: { success: true, providerId: "anthropic" }
Auth: required. Start an OAuth authorization flow for a provider.
Body: { "providerId": "...", "method": 0 }
Auth: required. Complete an OAuth authorization flow.
Body: { "providerId": "...", "code": "...", "method": 0 }