Authentication
Every API request carries a single Authorization: Bearer header. Server-to-server integrations use an API key; the dashboard uses short-lived session tokens issued by /v1/auth/login. This page covers the API-key path.
Account signup
POST/v1/signup
Public, limited to 5 attempts per IP per hour. Creates a tenant and its first admin user.
{
"organizationName": "Acme Corp", // required
"email": "ops@acme.example", // required
"name": "Acme Ops",
"password": "a-strong-passphrase", // required, min 12 chars
"accountType": "BUSINESS" // or "INDIVIDUAL"; default BUSINESS
}
// 201 →
{"tenantId": "…", "userId": "…", "status": "PENDING_EMAIL_VERIFICATION", "message": "…"}
Then confirm the address with the emailed token, or trigger a resend:
POST /v1/signup/verify-email {"token": "…"} // → {"status":"EMAIL_VERIFIED", …} POST /v1/signup/resend-verification {"email": "…"} // → always 202
New tenants start in PENDING_VERIFICATION: you can explore the API, create vaults, and register wallets, but value-moving endpoints stay blocked until identity verification (KYC/KYB) completes. Check progress with GET/v1/onboarding/status.
API keys
An API key is a keyId + secret pair sent as one bearer token, joined by a colon:
Authorization: Bearer qc_5f2a…e1:9c41…7d
# └─ keyId ─┘ └ secret ┘
| Part | Format |
|---|---|
keyId | qc_ + 32 hex characters |
secret | 64 hex characters — shown once at issuance; only a hash is stored |
Your first key is issued during onboarding in the dashboard (Keys page). The API surface manages existing keys only:
GET/v1/credentials
{"data": [
{"keyId": "qc_…", "tenantId": "…", "label": "prod-backend", "status": "ACTIVE",
"createdAt": "…", "expiresAt": null, "lastUsedAt": "…"}
]}
// secret material is never returned
POST/v1/credentials/rotate
{"keyId": "qc_…", "gracePeriodMinutes": 60} // grace default: 24 h
// 200 →
{"newKeyId": "qc_…", "secret": "…", // plaintext, shown once — store it now
"oldKeyId": "qc_…", "oldKeyExpiresAt": "…"}
The old key keeps working until the grace period ends, then returns 401 credential rotated and grace period expired. Rotate regularly and on any suspicion of exposure.
Scopes
Keys can be scoped to read, write, or admin. A key with no scopes has full access. Prefer the narrowest scope that works — reporting jobs need only read.
Access protections
- Brute-force lockout — 10 failed authentications within 15 minutes blocks the source for 15 minutes.
- IP allowlist — tenants can restrict API access to specific IPs or CIDR ranges; requests from elsewhere get
403. - Expiry — keys may carry an
expiresAt; expired keys return401 credential expired. - TLS only — plain HTTP is redirected; credentials sent over HTTP are considered compromised: rotate them.
X-Request-ID header to correlate your logs with Qustody's — the same ID is echoed back as requestId in every error body.
