Deze referentie is alleen in het Engels. Naar het Nederlandse REST API-overzicht

Diese Referenz gibt es nur auf Englisch. Zur deutschen REST-API-Übersicht

Cette référence existe uniquement en anglais. Aller à la présentation de l'API REST en français

Esta referencia solo está en inglés. Ir a la introducción de la API REST en español

Scopes and permissions

Scopes and permissions

Every operation needs a token scope and a permission on the user's role. How both are built, what each covers and which one to fix when a call is refused.

View as Markdown

Every /api/v2 request passes two separate checks, and every operation page states what each one needs.

CheckWhat it isWho controls itWhen it fails
Token scopeAn api: ability on the token you sent.Whoever created the token, or the person who approved the app.403 insufficient-token-scope, with required_ability listing the abilities that would have worked.
PermissionA permission on the role of the user the token belongs to.Whoever manages roles.403 insufficient-permission, with required_permission naming the missing one.

The token is only ever a ceiling. Permissions are read again on every request, so taking a permission away from a role narrows existing tokens at once, without touching them.

The two failures have different fixes. A scope failure needs a different token; a permission failure needs a role change. The full order of checks, from the organisation's switch to the record's state, is in Authentication.

How a scope is built

An ability is api:{class} or api:{class}:{prefix}.

  • class is read, write or destroy. On the API tokens page they are called Read, Write and Delete.
  • prefix is the resource, spelled as in the permission names, such as projects, project_management or work_types. API tokens maps each prefix to the name the token form shows.

Leave out the prefix and the ability covers every resource of its class: api:write satisfies an operation that asks for api:write:projects.

An app that signs people in with OAuth asks for these same strings as OAuth scopes, except the destroy class, which OAuth never offers.

The class ladder

Each class includes the ones below it: write includes read, and destroy includes both.

RequestClass requiredSatisfied by
GETreadread, write, destroy
POST, PATCHwritewrite, destroy
DELETEdestroydestroy

Every DELETE needs the destroy class, whether it deletes softly or for good. force=true is accepted on DELETE/projects/{project} alone. There it deletes the project for good, and it checks the same projects::delete permission as a soft delete. See Deleting and restoring.

Some operations list more than one scope. Any one of them is enough. They are the drive operations, where one endpoint serves items owned by a project, a customer, the organisation or a user, plus the comment and upload operations that work items and drive items share.

Token scopes

A token can carry every class with every resource, plus the three unnarrowed abilities api:read, api:write and api:destroy. 82 of them are named by at least one operation, and the table below lists those, with what each covers. api:write and api:destroy are not in it because no operation names them, but api:write satisfies every read and write, and api:destroy every read, write and delete.

ScopeResourcesOperations
api:read29 scopes
api:read//me2
api:read:absences/absences2
api:read:budget_groups/budget-groups2
api:read:budgets/budgets2
api:read:checkins/checkins2
api:read:company_branches/company-branches2
api:read:customer_categories/customer-categories2
api:read:customer_drive/comments/drive-documents/drive-folders/drive-items/notes/uploads12
api:read:customer_subscriptions/customer-subscriptions/subscription-items4
api:read:customers/contact-roles/contacts/customers6
api:read:events/events2
api:read:free_days/free-days2
api:read:furlough/furlough-balance-mutations2
api:read:holidays/holidays2
api:read:hours/timers2
api:read:invoices/invoices2
api:read:kanban/projects/tasks2
api:read:organization_drive/comments/drive-documents/drive-folders/drive-items/notes/uploads12
api:read:project_drive/comments/drive-documents/drive-folders/drive-items/notes/uploads12
api:read:project_management/comments/labels/sprints/subtasks/todos/uploads/work-item-links/work-items16
api:read:projects/project-links/projects4
api:read:sales_invoices/sales-invoice-rows/sales-invoices4
api:read:subscription_products/subscription-products2
api:read:subscription_types/subscription-type-items/subscription-types4
api:read:times/worklogs2
api:read:user_drive/comments/drive-documents/drive-folders/drive-items/notes/uploads12
api:read:users/users2
api:read:work_types/work-types2
api:read:workflows/workflow-statuses/workflow-transitions/workflows6
api:write27 scopes
api:write:absences/absences2
api:write:budget_groups/budget-groups2
api:write:budgets/budgets2
api:write:checkins/checkins2
api:write:company_branches/company-branches2
api:write:customer_categories/customer-categories2
api:write:customer_drive/comments/drive-documents/drive-folders/drive-items/notes13
api:write:customer_subscriptions/customer-subscriptions/subscription-items5
api:write:customers/contact-roles/contacts/customers7
api:write:events/events3
api:write:free_days/free-days2
api:write:furlough/furlough-balance-mutations2
api:write:holidays/holidays2
api:write:hours/timers2
api:write:invoices/invoices1
api:write:kanban/projects/tasks2
api:write:organization_drive/comments/drive-documents/drive-folders/drive-items/notes13
api:write:project_drive/comments/drive-documents/drive-folders/drive-items/notes13
api:write:project_management/comments/labels/sprints/subtasks/todos/work-items19
api:write:projects/project-links/projects5
api:write:sales_invoices/sales-invoice-rows/sales-invoices5
api:write:subscription_products/subscription-products3
api:write:subscription_types/subscription-type-items/subscription-types5
api:write:times/worklogs2
api:write:user_drive/comments/drive-documents/drive-folders/drive-items/notes13
api:write:work_types/work-types2
api:write:workflows/workflow-statuses/workflow-transitions/workflows6
api:destroy26 scopes
api:destroy:absences/absences1
api:destroy:budget_groups/budget-groups1
api:destroy:budgets/budgets1
api:destroy:checkins/checkins1
api:destroy:company_branches/company-branches1
api:destroy:customer_categories/customer-categories1
api:destroy:customer_drive/comments/drive-documents/drive-folders/drive-items/notes/uploads6
api:destroy:customer_subscriptions/customer-subscriptions/subscription-items2
api:destroy:customers/contact-roles/contacts/customers3
api:destroy:events/events1
api:destroy:free_days/free-days1
api:destroy:furlough/furlough-balance-mutations1
api:destroy:holidays/holidays1
api:destroy:hours/timers1
api:destroy:kanban/tasks1
api:destroy:organization_drive/comments/drive-documents/drive-folders/drive-items/notes/uploads6
api:destroy:project_drive/comments/drive-documents/drive-folders/drive-items/notes/uploads6
api:destroy:project_management/comments/labels/sprints/subtasks/todos/uploads/work-item-links/work-items8
api:destroy:projects/project-links/projects2
api:destroy:sales_invoices/sales-invoice-rows/sales-invoices2
api:destroy:subscription_products/subscription-products1
api:destroy:subscription_types/subscription-type-items/subscription-types2
api:destroy:times/worklogs1
api:destroy:user_drive/comments/drive-documents/drive-folders/drive-items/notes/uploads6
api:destroy:work_types/work-types1
api:destroy:workflows/workflow-statuses/workflow-transitions/workflows3

OAuth apps may ask for the read and write abilities only.

Permissions

67 permissions gate /api/v2. They are the same permissions plnnrly checks in the app, so an integration can do exactly what the user behind the token can do there, and no more.

A permission is {prefix}::{action}, such as projects::update. The prefix is usually the one a narrowed scope names, so api:write:projects and projects::update guard the same thing from two sides. Time is the exception: reading worklogs needs the scope api:read:times and the permission hours::read.

PermissionResourcesOperations
absences::manage/absences5
budget_groups::create/budget-groups1
budget_groups::delete/budget-groups1
budget_groups::read/budget-groups2
budget_groups::update/budget-groups1
budgets::create/budgets1
budgets::delete/budgets1
budgets::read/budgets2
budgets::update/budgets1
checkins::read/checkins2
company_branches::create/company-branches1
company_branches::delete/company-branches1
company_branches::read/company-branches2
company_branches::update/company-branches1
customer_categories::create/customer-categories1
customer_categories::delete/customer-categories1
customer_categories::read/customer-categories2
customer_categories::update/customer-categories1
customer_subscriptions::create/customer-subscriptions3
customer_subscriptions::delete/customer-subscriptions/subscription-items2
customer_subscriptions::read/customer-subscriptions/subscription-items4
customer_subscriptions::update/customer-subscriptions/subscription-items2
customers::create/contact-roles/contacts/customers4
customers::delete/contact-roles/contacts/customers3
customers::read/contact-roles/contacts/customers6
customers::update/contact-roles/contacts/customers3
events::manage_self/events6
free_days::manage/free-days5
furlough::create_for_yourself/furlough-balance-mutations1
furlough::manage/furlough-balance-mutations2
holidays::manage/holidays5
hours::read/timers/worklogs4
invoices::create/invoices1
invoices::read/invoices2
kanban::manage_self/projects/tasks5
project_drive::access/drive-documents/drive-folders/drive-items/notes10
project_drive::create/drive-documents/drive-folders/drive-items/notes16
project_management::manage_sprints/sprints5
project_management::manage_work_items/comments/labels/subtasks/todos/work-item-links/work-items21
project_management::view_active_sprint/sprints2
project_management::view_backlog/comments/labels/subtasks/todos/work-item-links/work-items13
projects::create/projects2
projects::delete/projects1
projects::read/projects2
projects::update/projects1
sales_invoices::create/sales-invoices3
sales_invoices::delete/sales-invoice-rows/sales-invoices2
sales_invoices::read/sales-invoice-rows/sales-invoices4
sales_invoices::update/sales-invoice-rows/sales-invoices2
subscription_products::create/subscription-products2
subscription_products::delete/subscription-products1
subscription_products::read/subscription-products2
subscription_products::update/subscription-products1
subscription_types::create/subscription-types3
subscription_types::delete/subscription-type-items/subscription-types2
subscription_types::read/subscription-type-items/subscription-types4
subscription_types::update/subscription-type-items/subscription-types2
users::read/users2
work_types::create/work-types1
work_types::delete/work-types1
work_types::read/work-types2
work_types::update/work-types1
workflows::create/workflow-statuses/workflow-transitions/workflows3
workflows::delete/workflow-statuses/workflow-transitions/workflows3
workflows::read/workflow-statuses/workflow-transitions/workflows6
workflows::update/workflow-statuses/workflow-transitions/workflows3
None. The record's own rules still apply.//checkins/furlough-balance-mutations/me/timers/uploads/worklogs15

The drive operations name project_drive::access or project_drive::create. For items owned by a customer, the organisation or a user, plnnrly checks the matching customer_drive, organization_drive or user_drive permission instead.

Operations that need no permission

A few operations need a valid token with the right scope and no permission at all. Their pages say so.

  • Discovery and GET/me.
  • Reading and cancelling an upload ticket.
  • Creating, changing and deleting your own worklogs, timers and check-ins, and reading your own furlough mutations. The record's own rules are the gate here, not a permission.

Other people's rows need a permission after all:

  • worklogs: times::update_others or times::delete_others, and times::update_others to log time for someone else with on_behalf_of_user_id
  • furlough mutations: furlough::view_all or furlough::manage

Permissions that change what a call does

Some permissions do not decide whether a call runs, but what it may do.

Fields with a permission of their own. Sending one of these fields without its permission answers 403 insufficient-permission naming the field, except is_overtime, which is dropped instead.

FieldOnPermissionWithout it
on_behalf_of_user_idworklogstimes::update_others403
debtor_codecustomersbilling_settings::update403
should_emailsales invoicessales_invoices::finalize403
is_approvedfurlough mutationsfurlough::manage403
is_overtimeworklogstimes::write_overtimeDropped, with an input_ignored warning in meta.warnings. The rest of the write is applied.

A dropped field does not fail the call, so check meta.warnings after every write.

Permissions that widen which rows you reach. Without them you see and change only your own rows:

  • times::update_others and times::delete_others: other people's worklogs
  • kanban::manage_for_others: other people's kanban tasks
  • events::manage_for_others: other people's agenda events
  • furlough::view_all and furlough::manage: other people's furlough mutations

Permissions a record's rules ask for. A few writes check a further permission on the record you write to, and answer 403 forbidden-by-policy without it:

  • projects::notes: adding a note to a project
  • times::write_on_others_tasks: logging time on a task that belongs to someone else

Each operation page names the permissions that apply to it.

What your organisation exposes

Call GET/ with any API token. It answers one entry per resource your organisation has, each with its permission_prefix, so you can match it with the tables above.

Discovery only leaves out resources of features your organisation does not have. It does not check your token or your role, so a listed resource can still answer 403 for you.