Browse the documentation

Permissions (scopes)

A key does only what you ticked. Permissions are named resource:access. A call outside its permissions answers 403 API_SCOPE_MISSING:<scope>, and the suffix names the permission to add.

The catalogue

PermissionRoutes it opens
account:readGET /me
account.notifications:readGET /account/notifications
account.access:readGET /account/access
account.ssh_keys:readGET /ssh-keys, GET /ssh-keys/{id}
account.ssh_keys:writePOST /ssh-keys, DELETE /ssh-keys/{id}
services:readGET /services, GET /services/{code}
services:writePATCH /services/{code}; POST /services/{code}/renew together with billing.invoices:pay
services.metrics:readGET /services/{code}/status, GET /services/{code}/metrics/history
services.addons:readGET /services/{code}/addons
services.power:writePOST /services/{code}/power; actions power, start_vps, stop_vps, reboot_vps
services.console:writePOST /services/{code}/console/command; action send_console_command
services.backups:readGET /services/{code}/backups; action backup_list
services.backups:writePOST /services/{code}/backups, DELETE /services/{code}/backups/{backupId}, POST /services/{code}/backups/restore; actions backup_create, backup_delete, backup_restore
services.firewall:readaction firewall_list
services.firewall:writeactions firewall_create, firewall_update, firewall_move, firewall_delete
services.rdns:writeaction rdns, including op: "get"
services.reinstall:writePOST /services/{code}/reinstall
billing.invoices:readGET /invoices, GET /invoices/{code}, GET /invoices/{code}/pdf
billing.credit_notes:readGET /credit-notes, GET /credit-notes/{code}/pdf
billing.balance:readGET /balance, GET /balance/transactions
billing.payment_methods:readGET /payment-methods
billing.invoices:payPOST /invoices/{code}/pay, POST /orders/{orderNumber}/pay, POST /services/{code}/renew; POST /orders when it pays
billing.saved_methods:chargethe four routes above when the funding is saved_method or account_default. Never used alone
catalog:readGET /catalog/products, GET /catalog/products/{shortname}
orders:readGET /orders, GET /orders/{orderNumber}
orders:writePOST /orders
tickets:readGET /tickets, GET /tickets/{ticketNumber}
tickets:writePOST /tickets, POST /tickets/{ticketNumber}/messages, POST /tickets/{ticketNumber}/close

Two routes fall outside the table: GET /me/key needs no permission, and GET /v1/openapi.json needs no key.

POST /services/{code}/actions/{action} has no fixed permission. It depends on the action sent: see the "actions" entries above and the full table in Managing services.

How a :write implies a :read

A :write implies the :read of the exact same name, and nothing else.

You holdYou also get
services:writeservices:read
services.backups:writeservices.backups:read
services.firewall:writeservices.firewall:read
account.ssh_keys:writeaccount.ssh_keys:read
orders:writeorders:read
tickets:writetickets:read

What does not carry over, despite the shared prefix:

  • services:write gives none of services.metrics:read, services.backups:read, services.addons:read, services.firewall:read.
  • billing.invoices:pay does not give billing.invoices:read: paying an invoice and reading it are two permissions.
  • services.rdns:write and services.reinstall:write have no matching :read.

What a permission alone does not buy

Effective rights are the intersection of the permission, the key's service restriction, and the state of the service.

CaseAnswer
Service outside the key's restriction404 SERVICE_NOT_FOUND
Suspended or cancelled service, relayed routes (/power, /console/command, /actions/{action})409 SERVICE_NOT_ACTIVE
Suspended or cancelled service, delegated routes (backups, restore, reinstall)400 SERVICE_NOT_ACTIVE
Service in dunning, same delegated routes400 SERVICE_IN_DUNNING
Service with no provisioned instance409 on relayed routes, 400 INSTANCE_NOT_PROVISIONED on delegated ones
Action the platform does not classify403 API_ACTION_NOT_ALLOWED:<action>

Choosing permissions

  • Start from what the integration does today. Widening a key asks for an identity confirmation, not a new key.
  • Monitoring or an accounting export needs :read permissions only.
  • billing.saved_methods:charge goes only on the key that has to charge, with a cap sized to the job. It is the only permission that forces a cap.
  • services.reinstall:write destroys the disk. Keep it on the key that reinstalls.