Skip to main content

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-USER-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 copies them from the target account when the key is issued and stores them on the key. Three properties follow from this:

  • A key issued for an administrator is an administrator key, bound to that administrator's tenant.
  • On each request the server checks the account only for identity - userSeq, userId, userName - and that it is still active. A key whose account is deactivated stops working.
  • Role and tenant checks, including access to /super-admin/**, use the values stored on the key, not the account's current role.

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.

Capture the key at issue time

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.
Changing an account's role does not change its existing keys

If an account's role changes after a key is issued, the key keeps the role it was issued with. Reissuing does not refresh it either. Issue a new key, and deactivate the old one.

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.

ScopeGrants
api:readRead access to the external API
api:writeWrite access to the external API
mcp:readRead access over MCP
mcp:writeWrite access over MCP

They cannot be combined freely. Only two combinations may be issued:

Allowed scope combinations
["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.

Scope is not a reliable permission boundary

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 pathManagesRequired role
/api/external/v1/users/api-keysKeys the calling account issued for itselfNone beyond the scope gate
/api/external/v1/admins/api-keysADMIN and USER keys in the caller's tenantADMIN
/api/external/v1/super-admin/api-keysEvery key in every tenantSUPER_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.

SurfaceTargetRule
UserAlways the calling accountuserSeq cannot be supplied
AdminSelf, or a USER in the same tenantAnother ADMIN is refused with API_KEY_012; an account in another tenant returns USER_005, the same as one that does not exist
Super adminSelf, or an ADMIN or USER in a named tenantAnother 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.

The target account must be ACTIVE. An account that does not exist or is not active returns USER_005 (404), and a tenantSeq naming a tenant that does not exist returns TENANT_001 (404).

Issue errors on the super admin surface:

CodeHTTPCause
API_KEY_006400The target account does not belong to tenantSeq
API_KEY_007400tenantSeq omitted for an administrator or user target
API_KEY_010400Scope combination not allowed
API_KEY_011400tenantSeq sent for a super administrator key
API_KEY_012403Target is another super administrator
USER_005404Target account does not exist or is not active
TENANT_001404The tenant named by tenantSeq does not exist
REQUEST_001400Request validation failed
A super administrator cannot use the admin surface to issue

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.

The user surface mints a key at the caller's own privilege

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, revoke all of them rather than only the one you know about, and then issue new keys.

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
ParameterTypeRequiredDescription
keyNamestringYesName for the key, up to 100 characters
keyPurposestringYesWhat the key is for, up to 255 characters
expireDatestringYesExpiry as an ISO-8601 local date-time; must be in the future
scopesarrayYesOne of the two allowed combinations
userSeqintegerNoTarget account; admin and super admin surfaces only
tenantSeqintegerConditionalTarget tenant; super admin surface only
Issue a key
curl -X POST "https://drive.example.com/api/external/v1/admins/api-keys" \
-H "Authorization: Bearer replace-with-your-TENANTADMIN-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"]}'
Issue response
{
"result": true,
"code": 201,
"message": "Created",
"data": {
"apiKey": "0Kf3XqN7bT2wYh5RmA8dLpV1cZ6sE4gJ"
}
}
Keys always expire

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
ParameterTypeRequiredDescription
psintegerYesPage size, minimum 1
cilongNoCursor - the last apiKeySeq of the previous page
tsintegerNoRestrict 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.

FieldTypeMeaning
apiKeySeqintegerKey identifier, and the pagination cursor
keyNamestringName given at issue
keyPurposestringStated purpose
maskedApiKeystringFirst eight and last four characters of the key
scopesarrayScopes held by the key
statusstringACTIVE or INACTIVE
expireDatestringExpiry
isExpiredbooleanWhether the expiry has passed
lastUsedDatestringLast authenticated request, or null if never used
registerDatestringWhen 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, which are null for super administrator keys. 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.

The user surface lists only self-issued keys

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
ParameterTypeRequiredDescription
expireDatestringYesNew 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. This is the only way to revive an expired key - reissuing or activating it does not change the expiry.

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 expiry does not change: an expired key that is reissued still fails with API_KEY_004 until you change the expiry.

Rotating the key you are calling with breaks that call's credential

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. Activating does not change the expiry, so an expired key stays unusable until its expiry is extended. 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. Changing the expiry, reissuing, activating, and deactivating all return it for an unknown apiKeySeq. The super admin surface can address keys in every tenant.

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.