Skip to content

Authentication ​

Personal access tokens ​

A personal access token starts with ahp_ and is shown once, when it is created. Send it as a bearer token, together with the id of the workspace the request is for:

http
GET /api/v2/api-tokens/me
Authorization: Bearer <token>
companyid: <company id>

A token acts as the person who created it. It reads what that person can open in the web app and changes what that person's role allows; it is never a way past project or sprint visibility. A token stops working on its next call when it is revoked, when it expires, or when its person is removed from the workspace.

A token is created from a signed-in session, in the web app. A token cannot create, change or delete tokens: the token management routes answer 403 to a token, except GET /api/v2/api-tokens/me.

The companyid header ​

A token belongs to one workspace. Every request made with a token carries that workspace's id in the companyid header, as 24 hexadecimal characters. A missing or malformed header is a 401.

Scopes ​

A token carries the scopes read and write. GET, HEAD and OPTIONS requests need read; every other method needs write, including a POST that only reads. A token without the scope a request needs gets a 403. A token created with no scopes named holds both.

Tokens limited to projects ​

A token can be created limited to some projects. Such a token is refused, with 403 and code: "token_limited_to_projects", on every route that cannot hold it to that list. Of the routes documented here, these accept it:

  • GET /api/v2/api-tokens/me
  • GET /api/public-v1/projects
  • GET /api/public-v1/tasks
  • GET /api/public-v1/tasks/:key
  • POST /api/v2/tasks/everything

On those routes it reads only its own projects; a project outside the list answers "not found". Each route below says whether it accepts such a token.

Agent tokens ​

A token created for an AI agent is an agent token. On top of everything above, an agent token is refused on every DELETE request, on the bulk task route, and on billing, member, permission and token management routes. Those refusals are 403 and are recorded in the audit log.

Token lifetime ​

A token can be given an expiry of 1 to 365 days when it is created. An instance running with API_TOKEN_STRICT requires both an expiry and at least one scope, can lower the longest lifetime with API_TOKEN_MAX_DAYS, and stops tokens that have no expiry 30 days after strict mode began (or after the token was created, if later). Without strict mode a token with no expiry keeps working until it is revoked.

OAuth ​

OAuth is offered for the MCP endpoint (/mcp) when the instance turns MCP_OAUTH on, and only there: an OAuth access token is not accepted by the REST routes in this reference. Its scopes are tasks:read, tasks:write, projects:read, docs:read, time:read, time:write, tasks:manage, docs:manage, chat:read. By default an access token lasts 15 minutes, a refresh token 30 days and a grant at most 90 days. See docs/MCP-AGENT-GUIDE.md.

Released under the AGPL-3.0 licence.