Skip to main content

Base URL

http://localhost:3001/api
The sidecar binds to port 3001 by default. All endpoints are prefixed with /api.

Authentication

Most endpoints require a JWT bearer token:
curl http://localhost:3001/api/tasks \
  -H "Authorization: Bearer <token>"
Obtain a token via:
  • POST /api/auth/login (username/password)
  • POST /api/auth/local/session (desktop auto-login)
  • GitHub OAuth flow
Tokens expire after 7 days and use HS256 signing.

Auth Levels

LevelHeaderDescription
requireAuthAuthorization: Bearer <token>Endpoint fails with 401 if no valid token
optionalAuthOptionalEndpoint works without auth but may return limited data
NoneNot neededPublic endpoint

Request Format

  • Content-Type: application/json
  • Method: GET, POST, PATCH, DELETE
  • Body: JSON for POST/PATCH requests

Response Format

Success

{
  "id": "uuid",
  "title": "Task title",
  "status": "todo",
  ...
}
Lists return JSON arrays. Single items return JSON objects.

Errors

{
  "error": "Human-readable error message",
  "details": {
    "fieldErrors": {},
    "formErrors": []
  }
}
StatusMeaning
400Validation error or bad request
401Missing or invalid authentication
403Forbidden (e.g., desktop-only endpoint)
404Resource not found
409Conflict (duplicate name, already exists)
500Internal server error
502External API failure (e.g., GitHub API)

Desktop Client Header

Some endpoints are restricted to the desktop app. They check for:
x-openlinear-client: desktop

Real-Time Events

The API provides a Server-Sent Events endpoint for live updates:
GET /api/events
See Real-Time Events for details.