Authentication
Authenticate API requests using Personal Access Tokens (PATs).
All API requests require authentication via a Personal Access Token (PAT). PATs provide long-lived API access for scripts, CI/CD pipelines, and integrations. They inherit the permissions of the user who created them.
PATs require a Pro plan subscription.
Creating a Token
- Open Settings > Account > Access Tokens in the Spedy dashboard.
- Click Create Token and give it a descriptive name (e.g. "CI Pipeline" or "Zapier Integration").
- Copy the token immediately -- it is only shown once and cannot be retrieved later.
Using a Token
Include the token in the Authorization header of every API request:
curl -H "Authorization: Bearer spedy_pat_abc123def456..." \
https://acme-corp.spedy.ai/api/v1/ticketsThe token is scoped to the organization of the user who created it. All requests are executed with that user's permissions.
Token Format and Security
- Tokens are prefixed with
spedy_pat_for easy identification. - Treat tokens like passwords -- never commit them to version control or share them in plain text.
- Use environment variables or a secrets manager to store tokens in CI/CD pipelines.
- Revoke tokens you no longer need.
Token Management Endpoints
List Tokens
GET /api/v1/me/tokensReturns all active tokens for the current user.
Example Response
{
"tokens": [
{
"id": "tok_abc123",
"name": "CI Pipeline",
"lastUsedAt": "2025-03-15T10:30:00Z",
"createdAt": "2025-01-10T08:00:00Z"
}
]
}Create Token
POST /api/v1/me/tokensCreate a new Personal Access Token. The full token value is only returned once in the response -- store it securely.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | A descriptive name for the token |
Example Request
{
"name": "CI Pipeline"
}Example Response
{
"id": "tok_abc123",
"name": "CI Pipeline",
"token": "spedy_pat_abc123def456...",
"createdAt": "2025-03-20T14:00:00Z"
}Get Token
GET /api/v1/me/tokens/{tokenId}Retrieve details of a specific token (without the secret value).
Revoke Token
DELETE /api/v1/me/tokens/{tokenId}Permanently revoke a token. This action cannot be undone. Returns 204 No Content on success.
Agent-User Tokens and Per-Token Scopes
An agent user has no login at all and authenticates only with tokens. Its tokens are minted through the Agents endpoints by an administrator or the agent's owner, never by the agent itself. Agent users are a Pro capability; MCP access itself is on every plan, so a loop can also run under a person's own token — it just has no identity of its own.
Both personal and agent tokens accept the same four scope options at creation time:
| Option | Type | Effect |
|---|---|---|
allowedBoardIds | string[] | Restricts the token to these projects, regardless of the user's memberships (max 100). Empty or omitted = every project the user can reach |
readOnly | boolean | Only read tools and GET requests. The token can look, not change |
denyDelete | boolean | Blocks every delete capability and DELETE request. Defaults to true for agent tokens, false for personal ones |
clientLabel | string | null | Free text naming the client that uses the token ("claude-code loop on ci-1"). It is what appears as the client on comments, time entries and status changes — and it outranks whatever the MCP client announces about itself |
expiresInDays | number | null | Lifetime in days (1–3650). Omit or null for a token that never expires |
Fail-closed
Scopes narrow, they never widen. A token can only ever do a subset of what its user may do, and a restriction that cannot be evaluated is treated as "not allowed":
- A token scoped to two projects cannot reach a third even when the user is a member of it.
- A request whose target board cannot be resolved is refused rather than waved through.
- Deactivating the agent, revoking the token or deleting the agent cuts every loop off immediately.
Scope errors
A refused request answers 403 with a stable code, so a loop can tell a scope problem from a permission problem:
| Code | Meaning |
|---|---|
PAT_READ_ONLY | The token is read-only and the request was a write |
PAT_DENY_DELETE | The token may not delete, and the request was a destructive one. Note the one narrow exception: releasing your own ticket claim is always allowed; only releasing another actor's claim trips this |
PAT_BOARD_NOT_ALLOWED | The target project is not in the token's allowedBoardIds |
The MCP surface raises the same codes, so the same loop logic works over both transports.
What agents are additionally subject to
For an agent user these apply over REST exactly as they do over MCP — there is no cheaper door:
- Status approval policy. Moving a ticket into a status the organization reserves for humans is refused with
403 AGENT_APPROVAL_REQUIRED, and a pending suggestion is recorded for a human to accept. - Time factor and weekly cap. Time an agent tracks lands as a draft with
PENDINGapproval, scaled by the agent's MCP time factor; once the weekly hours cap is reached, starting a timer fails withAGENT_HOURS_CAP_REACHED. - Concurrent claim ceiling. An agent may hold only so many ticket claims at once (default 3) —
403 CLAIM_LIMIT_REACHEDbeyond that.
OAuth 2.0
For external applications such as AI tools, IDE extensions, and MCP-capable clients, Spedy also supports OAuth 2.0 with PKCE. OAuth is available on all plans (including Starter and Trial) and is the recommended authentication method for third-party integrations.
See the OAuth 2.0 page for the full reference.