Authentication
Every request authenticates with an API Key sent as a bearer token. This page covers what a key is, what it can carry, and how to manage its lifecycle.
Authorization: Bearer replace-with-your-api-key
What a key represents
A key is issued on behalf of an account and acts as that account. The key's role and tenant are not supplied when issuing - the server reads them from the target account. Three properties follow from this:
- The key inherits the account's role, so a key issued for an administrator is an administrator key.
- The key is bound to the account's tenant, and a key whose account is deactivated stops working.
- Endpoints that check a role check the account's role, not anything stored on the key.
The key itself is 32 alphanumeric characters. It is returned in full exactly once, in the response that issues or
reissues it. Every later read returns only maskedApiKey, which shows the first eight and last four characters.
There is no way to recover the full value afterwards. If it is lost, reissue the key - which invalidates the old value
- rather than trying to read it back.
Tenant binding
An administrator or user key authenticates only on the domain of the tenant it was issued for. Calling another
tenant's domain with it fails with API_KEY_004, the same response as an unknown key.
A super administrator key has no tenant - its tenantSeq is null - so it authenticates on any tenant's domain.
Scopes
Four scope values exist.
| Scope | Grants |
|---|---|
api:read | Read access to the external API |
api:write | Write access to the external API |
mcp:read | Read access over MCP |
mcp:write | Write access over MCP |
They cannot be combined freely. Only two combinations may be issued:
["api:read", "mcp:read"]
["api:read", "api:write", "mcp:read", "mcp:write"]
Anything else is rejected with API_KEY_010, even when each individual value is valid. scopes is required on every
issue request regardless of the target account's role; an empty array fails validation with REQUEST_001.
Because both allowed combinations include api:read, every key passes the common scope gate. Several endpoint groups
then perform no further scope check - the whole admins and super-admin trees, the users, notifications,
config, web-office, pinned-folders, and API Key management endpoints. A read-only key can therefore perform write
operations in all of those. Treat scope as a hint about intent, not as an enforced restriction, and control access by
deciding who holds which key.
Three management surfaces
Which endpoints you use depends on whose keys you are managing.
| Base path | Manages | Required role |
|---|---|---|
/api/external/v1/users/api-keys | Keys the calling account issued for itself | None beyond the scope gate |
/api/external/v1/admins/api-keys | ADMIN and USER keys in the caller's tenant | ADMIN |
/api/external/v1/super-admin/api-keys | Every key in every tenant | SUPER_ADMIN |
Each surface offers the same six operations: list, issue, change the expiry, reissue, activate, and deactivate.
Who can issue a key for whom
The rule in every case is that you may issue for yourself or for an account of lower privilege, never for a peer.
| Surface | Target | Rule |
|---|---|---|
| User | Always the calling account | userSeq cannot be supplied |
| Admin | Self, or a USER in the same tenant | Another ADMIN is refused with API_KEY_012; an account in another tenant returns USER_005, the same as one that does not exist |
| Super admin | Self, or an ADMIN or USER in a named tenant | Another SUPER_ADMIN is refused with API_KEY_012 |
On the super admin surface, tenantSeq is required when the target is an administrator or user, and must not be sent
when issuing for yourself. Omitting it returns API_KEY_007, sending one that does not match the target's tenant
returns API_KEY_006, and sending one at all for a super administrator key returns API_KEY_011. Validation runs in
the order target account, then tenant, then scope, so the earliest failing check is the one reported.
POST /admins/api-keys refuses a super administrator caller with API_KEY_013, even though the role gate itself lets
super administrator keys through. Use the super admin surface instead. This guard applies only to issuing; the other
five admin key operations accept a super administrator caller.
POST /users/api-keys issues for the calling account with no caller restriction. An administrator key calling it
produces another administrator key, and a super administrator key produces another super administrator key. A leaked
key can therefore be used to mint further keys at the same privilege that survive revoking the original. When
responding to a suspected leak, list the account's keys and revoke all of them, not just the one you know about.
Issue a key
POST /api/external/v1/users/api-keys
POST /api/external/v1/admins/api-keys
POST /api/external/v1/super-admin/api-keys
| Parameter | Type | Required | Description |
|---|---|---|---|
keyName | string | Yes | Name for the key, up to 100 characters |
keyPurpose | string | Yes | What the key is for, up to 255 characters |
expireDate | string | Yes | Expiry as an ISO-8601 local date-time; must be in the future |
scopes | array | Yes | One of the two allowed combinations |
userSeq | integer | No | Target account; admin and super admin surfaces only |
tenantSeq | integer | Conditional | Target tenant; super admin surface only |
curl -X POST "https://drive.example.com/api/external/v1/admins/api-keys" \
-H "Authorization: Bearer replace-with-your-api-key" \
-H "Content-Type: application/json" \
-d '{"keyName": "Reporting job", "keyPurpose": "Nightly file inventory", "expireDate": "2027-04-02T23:59:59", "scopes": ["api:read", "mcp:read"]}'
{
"result": true,
"code": 201,
"message": "Created",
"data": {
"apiKey": "0Kf3XqN7bT2wYh5RmA8dLpV1cZ6sE4gJ"
}
}
There is no perpetual key. expireDate is required and must be a future instant. Plan rotation before the date you
choose.
List keys
GET /api/external/v1/users/api-keys
GET /api/external/v1/admins/api-keys
GET /api/external/v1/super-admin/api-keys
| Parameter | Type | Required | Description |
|---|---|---|---|
ps | integer | Yes | Page size, minimum 1 |
ci | long | No | Cursor - the last apiKeySeq of the previous page |
ts | integer | No | Restrict to one tenant; super admin surface only |
Results are ordered by apiKeySeq descending. pageSize and hasNext are always returned; nextCursor appears only
when there is a further page. hasNext is true whenever the page came back full, so a final page that exactly fills
ps reports another page that turns out to be empty.
| Field | Type | Meaning |
|---|---|---|
apiKeySeq | integer | Key identifier, and the pagination cursor |
keyName | string | Name given at issue |
keyPurpose | string | Stated purpose |
maskedApiKey | string | First eight and last four characters of the key |
scopes | array | Scopes held by the key |
status | string | ACTIVE or INACTIVE |
expireDate | string | Expiry |
isExpired | boolean | Whether the expiry has passed |
lastUsedDate | string | Last authenticated request, or null if never used |
registerDate | string | When the key was issued |
The admin and super admin listings also report the target account as userSeq, userId, userName, and roleType;
the super admin listing adds tenantSeq and tenantName. The user listing omits all of these because it only ever
returns your own keys.
Expired keys stay in the list. Passing ts on the super admin listing excludes super administrator keys, since those
belong to no tenant.
A key an administrator issued for you belongs to the administrator as issuer, so it does not appear here and cannot be revoked from here. If the key you are authenticating with was issued by an administrator, it cannot manage itself through this surface.
Change the expiry
PATCH /api/external/v1/users/api-keys/{apiKeySeq}/expire-date
PATCH /api/external/v1/admins/api-keys/{apiKeySeq}/expire-date
PATCH /api/external/v1/super-admin/api-keys/{apiKeySeq}/expire-date
| Parameter | Type | Required | Description |
|---|---|---|---|
expireDate | string | Yes | New expiry as an ISO-8601 local date-time; must be in the future |
Extending an already expired key to a future date makes it usable again.
Rotate a key
POST /api/external/v1/users/api-keys/{apiKeySeq}/reissue
POST /api/external/v1/admins/api-keys/{apiKeySeq}/reissue
POST /api/external/v1/super-admin/api-keys/{apiKeySeq}/reissue
Generates a new key value for the same record and sets its status back to ACTIVE. The response carries the new value
in full, and the previous value stops working immediately.
The old value is invalid from the moment the response is produced. Store the new value before making another request.
Suspend and restore
PATCH /api/external/v1/users/api-keys/{apiKeySeq}/deactivate
PATCH /api/external/v1/users/api-keys/{apiKeySeq}/activate
The same two paths exist on the admin and super admin surfaces. Deactivating is the fastest response to a suspected
leak: the key immediately fails authentication with API_KEY_004, and activating restores it. To make the change
permanent, reissue instead so the leaked value can never be restored.
Errors
API_KEY_004 with HTTP 401 covers every authentication failure - a missing header, an unrecognized value, a
deactivated key, an expired key, a key whose account is deactivated, and a key used on the wrong tenant's domain. The
response does not distinguish between them.
API_KEY_001 with HTTP 404 covers every key you cannot address - one that does not exist, and one outside the surface
you are calling. This is deliberate: it prevents probing for keys that belong to someone else.
REQUEST_001 reports request validation failures, and its message carries the list of fields that failed rather than
a fixed sentence. AUTH_009 means the calling key did not pass the role or scope gate.
See Errors for the full list.