Skip to main content

Authorization & Scopes

Three things decide what an API key can do:

  1. Scope: whether the key covers the whole organisation or one project.
  2. Permissions: the list of verb:resource grants stored on the key.
  3. The creator's role: a few time-entry actions also check the Align role of the user who created the key.

Key scopes​

ScopeWhat it reachesWho creates it
Organisation (organization)Every project in the organisation, plus organisation-wide endpointsAn admin, in Settings → Developer → API Keys
Project (project)One project onlyA manager, developer, tech lead or DevOps engineer, choosing a project they can access. Developers, tech leads and DevOps engineers have no Settings link in the sidebar; they open /admin/developer/keys directly.

What a project-scoped key can call​

A project-scoped key can reach only these paths. Anything else returns 403 scope_violation.

PathNotes
GET /me
/projects/{its project id}/...Entries, releases, members, wiki pages, time entries and summaries of that project.
/time-entries/{id}/...Only time entries in its project. Others return 404 not_found.
/wiki-pages/{id}

This means a project-scoped key cannot call GET /projects (the list), /entries/{id}, /comments/{id}, /attachments/{id}, /releases/{id} (including /evidence), /users, /webhooks, /integration-links, /integration/time-entries, /audit-events, /search or GET /time-entries. Use an organisation-scoped key for those.

Checking a key​

GET /api/v1/me
{
"apiKeyId": "f17d33b9-...",
"scope": "project",
"scopedProjectId": "proj-uuid-...",
"permissions": ["read:entry", "read:project", "write:entry"],
"organizationId": "ec597dd5-..."
}

Check scope and permissions when your integration starts, and fail with a clear message if something it needs is missing.

Permissions​

Each key carries a list of permissions. Every endpoint checks one; if the key does not hold it, the request returns 403 forbidden with a message naming the missing permission (for example Missing write:time_entry permission.).

ResourcePermissions
Projectsread:project, write:project, delete:project
Entriesread:entry, write:entry, delete:entry
Commentsread:comment, write:comment, delete:comment
Attachmentsread:attachment, write:attachment, delete:attachment
Releases (including evidence)read:release, write:release, delete:release
Webhooksread:webhook, write:webhook, delete:webhook
Audit logread:audit
Searchread:search
Snapshotsread:snapshot
Agreementsread:agreement
Wikiread:wiki, write:wiki, delete:wiki
Time entries (including time and cost summaries)read:time_entry, write:time_entry, delete:time_entry
Usersread:user, write:user
Project membersread:project_member, write:project_member, delete:project_member
Integration linkswrite:integration_link, delete:integration_link
SCIM usersread:scim_user, write:scim_user, delete:scim_user

GET /integration-links and GET /integration/time-entries/{id} check read:time_entry. POST /integration/time-entries checks write:integration_link. POST /webhooks/{id}/test checks write:webhook (it makes Align send a request; until ALN-731 it checked read:webhook). POST /ci/test-runs checks write:test_run; a key created before that permission existed is also accepted if it holds write:project. DELETE /time-entries/{id} checks delete:time_entry. The OpenAPI spec names the permission each operation checks in x-required-permission.

Default permissions​

If you do not click Customize when you create a key, it gets a default for its scope:

DefaultGrants
Organization default (organisation keys)Every permission above except delete:project_member and the SCIM permissions
Project default (project keys)read:project, read:entry, write:entry, read:comment, write:comment, read:attachment, write:attachment, read:release, read:search, read:wiki, read:time_entry, write:time_entry, write:test_run

The permission editor also offers Third-party app (read-mostly; cannot delete data or read the audit log) and Read only (every read: permission) as starting points.

A key whose permissions is null has full access. Keys created before per-key permissions existed are like this, and so, today, are the keys Align creates when a customer installs a Marketplace app. The key list labels it Full access (legacy). Give it an explicit list to narrow it.

Checks on the creator's role​

These actions also check the role of the user who created the key, in addition to the permission:

ActionRequirement
POST /time-entries/{id}/approveCreator is a manager or admin. Otherwise 403 forbidden ("Manager or admin role required to approve time entries.").
POST /time-entries/{id}/rejectCreator is a manager or admin. Otherwise 403 forbidden.
POST /time-entries/{id}/unlockCreator is a manager or admin. Otherwise 403 with reason: "insufficient_role" and details: { "required": "manager_or_admin", "current": "<role>" }.
POST /time-entries/{id}/submitCreator owns the time entry, or is a manager or admin.
Reading time entrieshourlyRateSnapshot is returned only when the creator is a manager or admin; otherwise it is null.

Add-ons and features​

Some endpoints also depend on the organisation's setup:

  • Time tracking. Time-entry, time-summary, cost-summary and integration sync endpoints return 402 with reason feature_disabled when time tracking is turned off for the organisation.
  • Illumera add-on. POST /users/invite, POST /users/bulk-invite, GET and PATCH /users/{id}, the project member endpoints, the wiki-page endpoints (except GET /projects/{id}/wiki-pages) and the time-entry endpoints (except cost summary and /integration/time-entries) require the organisation to have the Illumera add-on. Without it they return 403 with { "reason": "addon_required", "message": "…", "details": { "addon": "illumera", "upgradeUrl": "/settings/integrations" } }. The spec marks these operations with x-requires-addon: illumera. An admin turns it on in Settings → Integrations, under Add-ons.

Error reference​

Most errors use the envelope { "reason": "...", "message": "..." }, sometimes with details.

HTTPreasonMeaning
401missing_keyNo Authorization: Bearer or X-API-Key header
401invalid_keyKey not recognised
401key_revokedKey was revoked
401key_expiredKey has passed its expiry date
402feature_disabledTime tracking is off for the organisation
402plan_limitThe organisation's plan limit is reached (for example on POST /projects)
403feature_disabledThe Public API is turned off for the organisation
403organization_unavailableThe organisation is archived or deleted
403reconsent_requiredThe key belongs to a Marketplace app with a permission change the customer has not yet accepted
403installation_suspendedThe key belongs to a Marketplace app that was suspended because the re-consent deadline passed
403scope_violationA project-scoped key tried to reach another project or an organisation-wide endpoint
403forbiddenThe key lacks the permission, or the creator lacks the role
404not_foundThe resource does not exist or is outside the key's organisation
423suspendedThe organisation is suspended for billing
429rate_limitRate limit exceeded; see the Retry-After header