Permissions
The permission each Corporate API endpoint requires, and how a role is evaluated against it.
Before You Start
Read the following guides before proceeding:
| Guide | Why |
|---|---|
| Authentication | Permissions travel in the corporation token |
| Roles | How roles are created and assigned |
Overview
Every corporation-scoped endpoint declares a set of permissions. The permission set in the caller's
corporation token is evaluated against that declaration before the handler runs.
The evaluation has three rules:
Suoverrides everything. A holder ofSupasses every endpoint, whatever it declares.- The declared permissions are alternatives, not a conjunction. Holding any one of them is enough.
- An empty declaration admits any authenticated caller — any valid corporation token passes.
A caller that fails evaluation gets 403:
{
"error_reason": "ErrorPermissionDenied",
"error_description": "User does not have required permissions",
"error_category": {
"category": "CategoryForbidden",
"http_status_code": 403
}
}A caller whose token carries an empty permission set, calling an endpoint that declares any permission,
gets 403 with User does not have any permissions.
Permissions are resolved at login and frozen into the token. Changing a role, or moving an
employee to a different role, has no effect until that employee logs in again.
Permission Codes
These are the names accepted by POST /api/v1/roles and PUT /api/v1/roles/{roleId}. The numeric code
is what appears as the key in the token's permissions claim.
| Permission | Code | Grants |
|---|---|---|
Su | 101 | Everything. Cannot be assigned to a custom role |
CardSu | 102 | Every card operation |
CardCreate | 103 | Order new cards and create fee invoices |
CardViewDetails | 104 | Read PAN, CVV and PIN; read and confirm 3DS requests |
CardManage | 105 | Activate, block, unblock, close, rename; decide 3DS requests |
CardLimitManage | 106 | Change card limits |
CardView | 107 | List cards |
EmployeeSu | 108 | Every employee and role operation |
EmployeeManage | 109 | Invite, update and delete employees; change employee roles |
EmployeeView | 110 | List and search employees; list roles |
TransactionSu | 111 | Every transfer operation |
TransactionCreate | 112 | Estimate and execute transfers |
TransactionManage | 113 | Create, update and delete recipients |
TransactionView | 114 | Read transfer data |
AccountSu | 115 | Every bank account operation |
AccountCreate | 116 | Activate bank account details |
AccountManage | 117 | Modify account settings |
AccountView | 118 | Read bank accounts |
TransactionView, AccountManage and CardView alone do not unlock any endpoint that the table below
does not list — they exist so a role can express read-only intent that future endpoints will honour.
Endpoint Permission Matrix
Anonymous — no token
| Endpoint | Method |
|---|---|
/api/v1/config | GET |
/api/v1/global/capabilities | GET |
/api/v1/validation/rules | GET |
Partner token
| Endpoint | Method | Permissions |
|---|---|---|
/api/v1/token | POST | — (client credentials) |
/api/v1/config/tokens | GET | None — any valid token |
/api/v1/employees/corporations | GET | None |
/api/v1/corporations/register | POST | None — on-chain ownership is checked instead |
/api/v1/corporations/login | POST | None |
Corporation — profile and verification
| Endpoint | Method | Permissions |
|---|---|---|
/api/v1/corporations | GET | None |
/api/v1/corporations/freshdesk-id | PUT | None |
/api/v1/corporations/verification-token | POST | Su |
/api/v1/corporations/level-token | POST | Su |
Employees and roles
| Endpoint | Method | Permissions |
|---|---|---|
/api/v1/employees | GET | EmployeeSu, EmployeeManage, EmployeeView |
/api/v1/employees/search | GET | EmployeeSu, EmployeeManage, EmployeeView |
/api/v1/employees/{employeeId} | GET | None at the route; enforced in the handler — see below |
/api/v1/employees/invite | POST | EmployeeSu, EmployeeManage |
/api/v1/employees/{employeeId} | PUT | EmployeeSu, EmployeeManage |
/api/v1/employees/{employeeId}/role | PUT | EmployeeSu, EmployeeManage |
/api/v1/employees/{employeeId} | DELETE | EmployeeSu, EmployeeManage |
/api/v1/roles | GET | EmployeeSu, EmployeeManage, EmployeeView |
/api/v1/roles/{roleId} | GET | None |
/api/v1/roles | POST | EmployeeSu |
/api/v1/roles/{roleId} | PUT | EmployeeSu |
/api/v1/roles/{roleId} | DELETE | EmployeeSu |
GET /api/v1/employees/{employeeId}declares no permission because a caller may always read their
own employee record. Reading anyone else's record requiresSu,EmployeeSu,EmployeeManageor
EmployeeView, checked inside the handler.
Wallets and FX
| Endpoint | Method | Permissions |
|---|---|---|
/api/v1/wallets | GET | None |
/api/v1/wallets/global | POST | Su |
/api/v1/fx/estimate | POST | TransactionSu |
/api/v1/fx | POST | TransactionSu |
Cards
| Endpoint | Method | Permissions |
|---|---|---|
/api/v1/cards | GET | CardSu, CardView |
/api/v1/cards/{type}/fees/{country} | GET | CardSu, CardCreate, CardView |
/api/v1/cards/delivery/countries | GET | CardSu, CardCreate, CardView |
/api/v1/cards/delivery/methods/{country} | GET | CardSu, CardCreate, CardView |
/api/v1/cards/{type}/fees/{country}/payment | POST | CardSu, CardCreate |
/api/v2/cards/{type}/fees/{country}/payment | POST | CardSu, CardCreate |
/api/v1/cards/virtual, /api/v2/cards/virtual | POST | CardSu, CardCreate |
/api/v1/cards/plastic, /api/v2/cards/plastic | POST | CardSu, CardCreate |
/api/v1/cards/{cardId}/activate | PUT | CardSu, CardManage |
/api/v1/cards/{cardId}/block | PUT | CardSu, CardManage |
/api/v1/cards/{cardId}/unblock | PUT | CardSu, CardManage |
/api/v1/cards/{cardId}/close | PUT | CardSu, CardManage |
/api/v1/cards/{cardId}/name | PUT | CardSu, CardManage |
/api/v1/cards/{cardId}/limit | PUT | CardSu, CardLimitManage |
/api/v1/cards/{cardId}/details | POST | CardSu, CardViewDetails |
/api/v1/cards/{cardId}/cvv | POST | CardSu, CardViewDetails |
/api/v1/cards/{cardId}/pin | POST | CardSu, CardViewDetails |
/api/v1/confirmation/signature/verify | POST | CardSu, CardViewDetails |
/api/v1/confirmation/signature | POST | CardSu, CardViewDetails |
/api/v1/cards/3ds/requests | GET | CardSu, CardViewDetails |
/api/v1/cards/3ds/requests/{transactionId}/approve | POST | CardSu, CardManage |
/api/v1/cards/3ds/requests/{transactionId}/decline | POST | CardSu, CardManage |
/api/v1/cards/transfer/estimate | POST | CardSu |
/api/v1/cards/transfer | POST | CardSu |
Reading a 3DS request needs
CardViewDetails; deciding it needsCardManage. A role that can see
pending challenges but not approve them is the default outcome — grant both if one employee is meant
to handle the whole flow.
Bank accounts and transfers
| Endpoint | Method | Permissions |
|---|---|---|
/api/v1/bank/accounts | GET | TransactionSu, TransactionCreate, AccountView |
/api/v1/bank/accounts | POST | TransactionSu, AccountSu, AccountCreate |
/api/v1/bank/transfer/estimate | POST | TransactionSu, TransactionCreate |
/api/v2/bank/transfer/estimate | POST | TransactionSu, TransactionCreate |
/api/v1/bank/transfer | POST | TransactionSu, TransactionCreate |
/api/v3/bank/estimate/{corridor} | POST | TransactionSu, TransactionCreate |
/api/v3/bank/initiate/{corridor} | POST | TransactionSu, TransactionCreate |
/api/v3/bank/confirm/{corridor} | POST | TransactionSu, TransactionCreate |
/api/v1/bulk/transfer | POST | TransactionSu, TransactionCreate |
Recipients
| Endpoint | Method | Permissions |
|---|---|---|
/api/v1/recipients | GET | None |
/api/v1/recipients/{recipientId} | GET | None |
/api/v1/recipients/filter/catalog | GET | None |
/api/v1/recipients/filter/currency | GET | None |
/api/v1/recipients/filter/name | GET | None |
/api/v1/recipients/filter/type | GET | None |
/api/v1/recipients, /api/v2/recipients | POST | TransactionSu, TransactionManage |
/api/v1/recipients/{recipientId}, /api/v2/recipients/{recipientId} | PUT | TransactionSu, TransactionManage |
/api/v1/recipients/{recipientId} | DELETE | TransactionSu, TransactionManage |
/api/v1/recipients/{recipientId}/payment_details | POST | TransactionSu, TransactionManage |
/api/v1/recipients/{recipientId}/payment_details/{paymentDetailsId} | PUT | TransactionSu, TransactionManage |
/api/v1/recipients/{recipientId}/payment_details/{paymentDetailsId} | DELETE | TransactionSu, TransactionManage |
/api/v1/recipients/{recipientId}/usage | POST | TransactionSu, TransactionCreate, TransactionManage |
Activity
| Endpoint | Method | Permissions |
|---|---|---|
/api/v1/activity/feed | GET | None |
/api/v1/activity/statement/full | POST | None |
/api/v1/withdrawal/requests | GET | None |
Designing Roles
The permission model maps onto four operational areas — cards, employees, transactions, accounts — each
with its own *Su. A practical split:
| Function | Permissions |
|---|---|
| Finance operator — pays suppliers, cannot change who is paid | TransactionCreate |
| Finance manager — maintains the payee book and pays | TransactionCreate, TransactionManage |
| Card administrator | CardCreate, CardManage, CardLimitManage, CardView |
| Cardholder — sees their own card details only | CardView, CardViewDetails |
| People operations | EmployeeManage, EmployeeView |
| Auditor | CardView, TransactionView, AccountView, EmployeeView |
Su is reserved for the on-chain owner. It is refused by POST /api/v1/roles and
PUT /api/v1/roles/{roleId} with 400 and Su permission is not allowed for custom roles.
Three endpoints require Su outright and cannot be delegated through a custom role:
POST /api/v1/corporations/verification-token, POST /api/v1/corporations/level-token and
POST /api/v1/wallets/global.
Updated 20 days ago

