Skip to content

Scopes ​

OAuth access tokens carry scopes — strings declaring which categories of data the token can read or write. The API checks the scope on every request and rejects calls that aren't covered.

Direct kAuth bypasses scopes

The direct kAuth path always grants the admin meta-scope. This page is about OAuth tokens.

Naming ​

Scopes follow the pattern {resource}:{action}:

  • {resource} — the URL slug (e.g. projects, invoices, time-entries)
  • {action} — either read (GET, POST /query) or write (POST, PATCH, DELETE)

A token with projects:read can list and fetch projects but cannot create or modify them.

Meta-scopes ​

Three scopes expand to broader sets:

ScopeExpands to
adminEverything below — full read and write across every resource.
readEvery {resource}:read scope.
writeEvery {resource}:read and {resource}:write scope.

If a token has any meta-scope, it can hit any endpoint that meta-scope covers — you don't have to list every individual scope.

Per-resource scopes ​

ResourceRead scopeWrite scope
Projectsprojects:readprojects:write
List Itemslist-items:readlist-items:write
Invoicesinvoices:readinvoices:write
AIA Invoicesaia-invoices:readaia-invoices:write
Contractscontracts:readcontracts:write
Clientsclients:readclients:write
Vendorsvendors:readvendors:write
Milestonesmilestones:readmilestones:write
Tasks(uses projects:*)(uses projects:*)
Allocationsallocations:readallocations:write
Paymentspayments:readpayments:write
Purchasespurchases:readpurchases:write
Purchase Itemspurchase-items:readpurchase-items:write
Items (Catalog)items:readitems:write
Documentsdocuments:readdocuments:write
Billsbills:readbills:write
Departmentsdepartments:readdepartments:write
Resourcesresources:readresources:write
Submittalssubmittals:readsubmittals:write
Assetsassets:readassets:write
Service Ticketsservice-tickets:readservice-tickets:write
Time Entriestime-entries:readtime-entries:write
Billablesbillables:readbillables:write
Usersusers:readusers:write

Identity / utility scopes ​

These cover the standard OIDC identity endpoints and don't gate any resource:

ScopePurpose
openidIdentifies the token as an OIDC ID token request. Required if you want an id_token from the authorization endpoint.
profileInclude the user's profile info in the ID token.
offline_accessIssue a refresh token alongside the access token. Required if you want managed refresh.

GET /api/v2/me, /company, /settings, and /valid don't require any specific scope — any authenticated request can hit them.

Requesting scopes ​

In any OAuth flow, list scopes in the scope parameter (space-separated):

Authorization Code:

http
GET /oauth/auth?
  response_type=code&
  client_id=YOUR_CLIENT&
  redirect_uri=...&
  scope=openid+offline_access+projects:read+invoices:read&
  ...

Client Credentials:

http
POST /oauth/token
grant_type=client_credentials
client_id=YOUR_CLIENT
client_secret=YOUR_SECRET
scope=projects:read+invoices:read

The granted scopes are the intersection of:

  • What you requested
  • What the OAuth client is configured to allow (set in the developers portal)
  • For user-authorized flows, what the user consented to during the authorization screen

Inspect the granted scopes on a token via GET /api/v2/me or by decoding the access token JWT.

Legacy v1 scopes ​

Three resources were renamed for v2; the legacy scope names still exist (the v1 surface uses them) but new clients should request the v2 scope names:

Legacy (v1)Modern (v2)Reason
tickets:*service-tickets:*Clearer in OpenAPI docs
time:*time-entries:*"time" was ambiguous
items:* (in v1 meaning ServiceCatalog)items:* (still, same model) + new purchase-items:* for the previously-bundled PO line itemsCleared up a slug collision

A token granted tickets:read can read v1 ticket endpoints but won't satisfy service-tickets:read on v2 unless you also include a meta-scope. The practical answer: request both forms during the transition, or request the read meta-scope and cover everything.

Granting scopes to a client ​

Scopes a client is allowed to request are configured per-client in the developers portal under Clients → Edit → Scopes. The token's effective scope is always a subset of what the client is configured to allow.

Principle of least privilege

Don't ask for admin if you only need projects:read. Narrower scopes mean less blast radius if a token is leaked, easier security review, and a better experience for users on the consent screen.