Appearance
Organization Token Management
Overview
Organization access tokens (also referenced as OrganizationAccessToken in the backend) enable server-to-server calls and device client onboarding without storing user credentials. Tokens inherit the organization scope of their issuer, and their access levels are determined by an attached AccessConfig.
- Base Path:
/api/v2/organization/tokens/
Endpoint Summary
| Method | Path | Description | Notes |
|---|---|---|---|
| GET | /api/v2/organization/tokens/ | List all tokens issued for the active organization | See List Tokens. |
| POST | /api/v2/organization/tokens/ | Create a new token with optional expiration and project scope | See Create Token. |
| PUT/PATCH | /api/v2/organization/tokens/{id}/ | Update token metadata (name, is_active, expires_at, access_config) | See Update Token. |
| DELETE | /api/v2/organization/tokens/{id}/ | Permanently revoke a token | See Delete Token. |
Endpoints
List Tokens
Retrieve all access tokens tied to the organization in request.organization.
http
GET /api/v2/organization/tokens/
Authorization: Bearer <owner_token>json
[
{
"id": 12,
"name": "Factor export pipeline",
"token": "rjm9czn9...",
"is_active": true,
"expires_at": "2024-12-31T23:59:59Z",
"created_at": "2024-01-08T10:00:00Z",
"last_used_at": "2024-02-15T02:00:00Z",
"access_config": {
"role": "manager",
"all_projects": false,
"projects": ["prd-greenhouse", "prd-coldroom"]
}
}
]Create Token
http
POST /api/v2/organization/tokens/
Authorization: Bearer <owner_token>
Content-Type: application/json
{
"name": "Webhook relay",
"expires_at": "2024-12-31T23:59:59Z",
"access_config": {
"role": "operator",
"projects": ["prd-greenhouse"]
}
}| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Human-readable label for auditing |
expires_at | ISO 8601 string | No | Null yields a non-expiring token |
access_config.role | string | No | Defaults to readonly; allowed values: readonly, operator, manager |
access_config.all_projects | boolean | No | Grants access to every project if true |
access_config.projects | list[string] | No | Explicit project IDs when all_projects=false |
Response mirrors the list payload with generated token and timestamps. Store the token value securely; it cannot be retrieved after creation.
Update Token
http
PATCH /api/v2/organization/tokens/{token_id}/
Authorization: Bearer <owner_token>
Content-Type: application/json
{
"name": "Webhook relay (deprecated)",
"is_active": false,
"access_config": {
"role": "readonly",
"projects": []
}
}Supported fields match the creation payload. Use this endpoint to rotate permissions or disable compromised tokens without deleting them.
Delete Token
http
DELETE /api/v2/organization/tokens/{token_id}/
Authorization: Bearer <owner_token>Returns HTTP 204 if the token existed and has been revoked. Downstream services should detect 401/403 responses once the token is deleted.
Error Codes
| Status | Code | Description |
|---|---|---|
| 401 | UNAUTHORIZED | Missing or invalid owner credentials |
| 403 | FORBIDDEN | Caller is not the organization owner |
| 404 | TOKEN_NOT_FOUND | Token ID does not belong to the organization |
| 400 | BAD_REQUEST | Validation error (e.g., duplicate name, invalid expiration) |
Operational Notes
- Token Rotation: Use PATCH to set
is_active=falsebefore issuing a replacement token. This avoids downtime while clients migrate. - Last Used Timestamp: The backend updates
last_used_atautomatically whenever the token authenticates an API call, enabling stale token cleanup. - Access Config Consistency: The API enforces valid role values and ensures
projectsmatches existingproject_idvalues. Requests with unknown projects are rejected with400 BAD_REQUEST. - Security: Treat tokens like passwords. Store them in a secrets manager and avoid embedding them in firmware that ships publicly.
