Accesses Management
An Access is a login bound to your Business Account. Each access has its own credentials (email + password), MFA, and a granular set of permissions that gate which Avenia API operations it can call. Accesses can be issued to teammates, services, or signers without sharing the original admin credentials.
This guide is the complete reference for the /v2/auth/accesses API. For a higher-level overview of how an access relates to your account and subaccounts, see About Login → Access.
You must have TOTP MFA enabled on the calling access to create, update, or delete accesses, and to manage the subaccount blacklist. Click here to learn how to set this up.
Only admin accesses can create, update, or delete other accesses. The first access of your Business Account is the admin by default.
Permissions Reference
Permissions are passed as a permissions object in POST and PATCH requests. They are returned inside accessPermission on GET responses.
| Field | Type | Default | Description |
|---|---|---|---|
admin | boolean | false | Read-only on responses. Admin accesses can manage other accesses, API keys, and the blacklist. |
payOut | boolean | — | Allows pay-out operations (e.g. stable → fiat, off-ramp) and on-chain transfers to external wallets. |
viewOnly | boolean | — | Read-only access. When true, the access can list balances and transactions but cannot move funds. |
markup | boolean | true | Allows the access to set/override quote markup. Optional on create/update. |
beneficiary | boolean | true | Allows the access to manage beneficiaries (bank accounts, wallets). Optional on create/update. |
enforceAllowedBeneficiaries | boolean | false | When true, the access can only operate on a curated allow-list of beneficiaries. Optional on create/update. |
operationRequester | boolean | false | Puts the access's sensitive operations under multi-signature approval. See Multi-Signature Operations. |
operationApprover | boolean | false | Lets the access approve or reject the operations of the requesters it is assigned to. See Multi-Signature Operations. |
Pay-in (deposits) and currency conversion are available to any access that is not viewOnly — they are not gated by a separate permission. Outbound movement of funds (pay-outs and on-chain transfers) is governed by payOut.
Additional Fields
These fields are accepted alongside permissions in the request body:
| Field | Type | Required | Description |
|---|---|---|---|
blacklistedSubAccountIds | array of string | No | UUIDs of subaccounts this access is not allowed to operate on. Persisted into the access JWT and merged with prior blacklist entries. |
approverAccessIds | array of string | No | For a multi-sig requester: the access ids of its approvers. |
minApprovals | integer | With approverAccessIds | For a multi-sig requester: approvals needed to reach the quorum, between 1 and the number of approvers. The approval that reaches it executes the operation on behalf of the requester. |
multisigNotifications | boolean | No | Whether the access receives multi-sig emails. |
Limits
- Maximum of 100 accesses per Business Account (admin included). Further
POST /accesses/calls return HTTP 400. - Email is normalized to lowercase server-side.
- The access creation token sent by email is valid for 10 minutes.
Create Access (Step 1 — Invite)
Sends an email to the new access with a token to set their password. The calling access must be admin with MFA enabled.
Endpoint
Body Parameters
| Field | Type | Required | Description |
|---|---|---|---|
otp | string | Yes | TOTP code from the admin's authenticator app. |
email | string | Yes | Email of the new access. Must be a valid address, ≤ 256 characters. |
permissions | object | Yes | Permission flags. See Permissions Reference. |
permissions.payOut | boolean | Yes | Pay-out permission (also gates on-chain transfers). |
permissions.viewOnly | boolean | Yes | Read-only permission. |
permissions.markup | boolean | No | Defaults to true. |
permissions.beneficiary | boolean | No | Defaults to true. |
permissions.enforceAllowedBeneficiaries | boolean | No | Defaults to false. |
blacklistedSubAccountIds | array of string | No | Subaccount UUIDs this access cannot operate on. |
Request body
{
"otp": "999999",
"email": "your.new.access.email@provider.com",
"permissions": {
"payOut": true,
"viewOnly": false,
"markup": true,
"beneficiary": true,
"enforceAllowedBeneficiaries": false
},
"blacklistedSubAccountIds": []
}
Request example
curl -X POST "https://api.sandbox.avenia.io:10952/v2/auth/accesses/" \
-H "Authorization: Bearer eyJhdXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
-H "Content-Type: application/json" \
-d '{
"otp": "999999",
"email": "your.new.access.email@provider.com",
"permissions": {
"payOut": true,
"viewOnly": false
}
}'
A 200 OK is returned and an email with a creation token is sent to the new access. The token is valid for 10 minutes.
Validate Access (Step 2 — Set Password)
The recipient of the invitation email completes the access creation by setting a password. No bearer token is required for this call — only the email token returned in the invitation URL.
Endpoint
URL Parameters
| Field | Type | Description |
|---|---|---|
token | string | Email token from the invitation link (10-min TTL). |
Body Parameters
| Field | Type | Required | Description |
|---|---|---|---|
password | string | Yes | New password for the access. |
confirmPassword | string | Yes | Must match password. |
Request body
{
"password": "UseAStrongPassword123!",
"confirmPassword": "UseAStrongPassword123!"
}
Request example
curl -X POST "https://api.sandbox.avenia.io:10952/v2/auth/accesses/validate/eyJhdXXXXXXXXXXXXXXX" \
-H "Content-Type: application/json" \
-d '{
"password": "UseAStrongPassword123!",
"confirmPassword": "UseAStrongPassword123!"
}'
A 200 OK confirms the password was set and the access is ready to log in.
List Accesses
Returns all accesses linked to the calling Business Account. Optional query parameters filter by email or by individual permission flags.
Endpoint
Query Parameters
| Field | Type | Description |
|---|---|---|
email | string | Filter by email (substring match). |
payOut | boolean | Filter by payOut permission. |
viewOnly | boolean | Filter by viewOnly permission. |
createdAfter | int64 | Unix epoch timestamp in milliseconds (UTC) — e.g. 1700000000000. Returns accesses created on or after this instant (createdAt >= createdAfter). |
createdBefore | int64 | Unix epoch timestamp in milliseconds (UTC) — e.g. 1800000000000. Returns accesses created on or before this instant (createdAt <= createdBefore). |
createdAfter / createdBefore are Unix epoch timestamps in milliseconds, UTC (13 digits for current dates, e.g. 1700000000000) — not seconds (10 digits). If you have a value in seconds, multiply it by 1000. Both bounds are inclusive here (createdAt >= createdAfter and createdAt <= createdBefore), and the returned createdAt is an RFC3339 UTC string ending in Z. Convert local date boundaries to UTC before computing the epoch.
Request example
curl -X GET "https://api.sandbox.avenia.io:10952/v2/auth/accesses?email=your.new.access.email@provider.com&payOut=true" \
-H "Authorization: Bearer eyJhdXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
Response
{
"accesses": [
{
"id": "00000000-0000-0000-0000-000000000000",
"email": "your.new.access.email@provider.com",
"createdAt": "2025-02-07T19:54:17.727744Z",
"updatedAt": "2025-02-07T19:54:17.727744Z",
"frozenUntil": "0001-01-01T00:00:00Z",
"accessPermission": {
"id": "11111111-1111-1111-1111-111111111111",
"admin": false,
"payOut": true,
"viewOnly": false,
"markup": true,
"beneficiary": true,
"enforceAllowedBeneficiaries": false,
"updatedAt": "2025-02-07T19:54:17.727744Z"
},
"mfa": {
"id": "22222222-2222-2222-2222-222222222222",
"createdAt": "2025-02-18T00:36:47.329722Z",
"updatedAt": "2025-02-18T00:36:47.329722Z"
}
}
]
}
Get Access by ID
Endpoint
URL Parameters
| Field | Type | Required | Description |
|---|---|---|---|
access-id | string | Yes | UUID of an existing access. |
Request example
curl -X GET "https://api.sandbox.avenia.io:10952/v2/auth/accesses/00000000-0000-0000-0000-000000000000" \
-H "Authorization: Bearer eyJhdXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
Response
{
"access": {
"id": "00000000-0000-0000-0000-000000000000",
"email": "your.new.access.email@provider.com",
"createdAt": "2025-02-07T19:54:17.727744Z",
"updatedAt": "2025-02-07T19:54:17.727744Z",
"frozenUntil": "0001-01-01T00:00:00Z",
"accessPermission": {
"id": "11111111-1111-1111-1111-111111111111",
"admin": false,
"payOut": true,
"viewOnly": false,
"markup": true,
"beneficiary": true,
"enforceAllowedBeneficiaries": false,
"updatedAt": "2025-02-07T19:54:17.727744Z"
}
}
}
Update Access Permissions
Updates the permissions and blacklist of an existing access. Caller must be admin with MFA enabled.
Endpoint
Body Parameters
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | UUID of the access to update. |
otp | string | Yes | TOTP code from the admin's authenticator app. |
permissions | object | Yes | Same fields as in Create. |
blacklistedSubAccountIds | array of string | No | Replaces the access blacklist. Use the dedicated Blacklist endpoints for incremental updates. |
Request body
{
"id": "00000000-0000-0000-0000-000000000000",
"otp": "999999",
"permissions": {
"payOut": true,
"viewOnly": false,
"markup": false,
"beneficiary": true,
"enforceAllowedBeneficiaries": true
},
"blacklistedSubAccountIds": []
}
Request example
curl -X PATCH "https://api.sandbox.avenia.io:10952/v2/auth/accesses/" \
-H "Authorization: Bearer eyJhdXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
-H "Content-Type: application/json" \
-d '{
"id": "00000000-0000-0000-0000-000000000000",
"otp": "999999",
"permissions": {
"payOut": true,
"viewOnly": false
}
}'
A 200 OK confirms the update.
Delete Access
Deletes an existing access and invalidates its JWT and refresh tokens. Caller must be admin with MFA enabled.
Endpoint
URL Parameters
| Field | Type | Required | Description |
|---|---|---|---|
access-id | string | Yes | UUID of the access to delete. |
Query Parameters
| Field | Type | Required | Description |
|---|---|---|---|
otp | string | Yes | TOTP code from the authenticator app. |
Request example
curl -X DELETE "https://api.sandbox.avenia.io:10952/v2/auth/accesses/00000000-0000-0000-0000-000000000000?otp=999999" \
-H "Authorization: Bearer eyJhdXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
Subaccount Blacklist
Each access can be restricted from operating on a list of subaccounts. The blacklist is stored on the access itself and is enforced at JWT issuance — blacklisted subaccounts will not appear in subaccount listings for that access and any operation against them is rejected.
All blacklist endpoints require admin with MFA enabled on the calling access.
Add Account to Blacklist
Endpoint
URL Parameters
| Field | Type | Required | Description |
|---|---|---|---|
access-id | string | Yes | UUID of the target access. |
Body Parameters
| Field | Type | Required | Description |
|---|---|---|---|
accountId | string | Yes | UUID of the subaccount to blacklist. |
otp | string | Yes | TOTP code from the admin's authenticator app. |
Request body
{
"accountId": "55555555-5555-5555-5555-555555555555",
"otp": "999999"
}
Request example
curl -X POST "https://api.sandbox.avenia.io:10952/v2/auth/accesses/00000000-0000-0000-0000-000000000000/blacklist" \
-H "Authorization: Bearer eyJhdXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
-H "Content-Type: application/json" \
-d '{
"accountId": "55555555-5555-5555-5555-555555555555",
"otp": "999999"
}'
List Blacklisted Accounts for an Access
Endpoint
Request example
curl -X GET "https://api.sandbox.avenia.io:10952/v2/auth/accesses/00000000-0000-0000-0000-000000000000/blacklist" \
-H "Authorization: Bearer eyJhdXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
Response
{
"accountIds": [
"55555555-5555-5555-5555-555555555555",
"66666666-6666-6666-6666-666666666666"
]
}
Remove Account from Blacklist
Endpoint
URL Parameters
| Field | Type | Required | Description |
|---|---|---|---|
access-id | string | Yes | UUID of the target access. |
account-id | string | Yes | UUID of the subaccount to un-blacklist. |
Query Parameters
| Field | Type | Required | Description |
|---|---|---|---|
otp | string | Yes | TOTP code from the authenticator app. |
Request example
curl -X DELETE "https://api.sandbox.avenia.io:10952/v2/auth/accesses/00000000-0000-0000-0000-000000000000/blacklist/55555555-5555-5555-5555-555555555555?otp=999999" \
-H "Authorization: Bearer eyJhdXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
Current Access Information
Returns the access tied to the bearer token currently calling the API — useful for sanity-checking which access (and which permissions) a given token represents.
Endpoint
Request example
curl -X GET "https://api.sandbox.avenia.io:10952/v2/account/access-info" \
-H "Authorization: Bearer eyJhdXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
Common Errors
| HTTP | Reason |
|---|---|
| 400 | you need to be admin to create an access — caller is not an admin access. |
| 400 | you need to activate your 2fa — calling access has no MFA configured. |
| 400 | you've reached the maximum number of accesses created — 100-access cap hit. |
| 400 | invalid field: email / invalid field: otp. |
| 401 | Missing or invalid bearer token. |
| 403 | Access lacks the admin permission for an admin-only endpoint. |
Conclusion
You now have the complete API surface for managing accesses on Avenia API:
- ✅ Create + validate a new access (two-step email flow)
- ✅ Granular permissions (pay-out, view-only, markup, beneficiary, enforce-allowed-beneficiaries)
- ✅ Subaccount blacklist per access
- ✅ List / inspect / update / delete accesses
- ✅ Inspect the current bearer's access