Skip to content

Errors & Limits

All errors return a JSON body with an error field:

{
"error": "description of what went wrong"
}

The HTTP status code indicates the error category. The error message provides a human-readable description.


CodeNameWhen it’s returned
200OKRequest succeeded
400Bad RequestInvalid input — missing required fields, invalid format, unsupported value
401UnauthorizedMissing, invalid, or expired API key / session token
403ForbiddenYour role lacks the required permission for this endpoint
404Not FoundResource doesn’t exist, doesn’t belong to your tenant, or was already revoked
409ConflictDuplicate — email already registered, tenant slug taken, domain already claimed
500Internal ErrorServer-side error — retry or contact support

ErrorCauseFix
unauthorizedMissing or invalid Authorization headerInclude Authorization: Bearer <token> with a valid API key or session token
unauthorized (after working)Session or API key expiredRe-login or create a new API key
ErrorCauseFix
role 'viewer' lacks permission: credentials:issueYour role doesn’t have the required permissionAsk a tenant admin to upgrade your role, or use a different API key
API key missing scope: dids:createAPI key was created with restricted scopesCreate a new API key with the needed scope, or one with no scope restrictions
ErrorCauseFix
monthly credential issuance limit reached (100)Plan’s monthly credential quota exhaustedUpgrade your plan or wait for the next billing month
DID limit reached (1)Maximum DIDs for your planUpgrade your plan or deactivate unused DIDs
tenant member limit reached (1)Maximum team members for your planUpgrade your plan
ErrorCauseFix
DID did:key:z6Mk... not found in tenantThe DID doesn’t belong to your tenantUse a DID you created in your own tenant
issuer DID is deactivatedTrying to issue with a deactivated DIDCreate a new DID
credential not found or already revokedCredential doesn’t exist or was already revokedCheck the credential ID
invalid role_idRole UUID doesn’t existUse GET /v1/roles to list valid role IDs
email already registeredEmail taken by another userUse a different email or login with the existing account
tenant slug already takenAnother tenant uses this slugChoose a different slug
ErrorCauseFix
email required, password must be >= 8 charsRegistration validation failedProvide a valid email and password of 8+ characters
score must be 0-100Trust attestation score out of rangeUse an integer between 0 and 100
weight must be 0.0-1.0Trust attestation weight out of rangeUse a decimal between 0.0 and 1.0
invalid assurance levelUnrecognized level stringUse: low, substantial, or high
unsupported formatCredential format not recognizedUse jwt_vc_json or vc+sd-jwt

Rate limits are applied per tenant, per minute. When exceeded, the API returns 429 Too Many Requests.

PlanRequests/minuteBurst
Developer (free)1020
Startup ($49)100200
Business ($199)1,0002,000
Enterprise10,00020,000
const result = await fetch('/v1/credentials/issue', { ... });
if (result.status === 429) {
const retryAfter = result.headers.get('Retry-After');
await sleep(parseInt(retryAfter || '60') * 1000);
// retry
}

ResourceDeveloperStartupBusinessEnterprise
Credentials/month1001,00010,000Unlimited
DIDs1525Unlimited
Team members1525Unlimited
Custom rolesNoNoYesYes
Custom domainsNoNoYesYes
API keysUnlimitedUnlimitedUnlimitedUnlimited
WebhooksUnlimitedUnlimitedUnlimitedUnlimited
Compliance frameworksAll 7All 7All 7All 7
Trust APIYesYesYesYes
DIDCommYesYesYesYes

Check current usage and remaining quota:

Terminal window
curl https://api.baseid.cloud/v1/admin/usage \
-H "Authorization: Bearer bsk_live_..."

Upgrade your plan:

Terminal window
curl -X POST https://api.baseid.cloud/v1/admin/billing/upgrade \
-H "Authorization: Bearer bsk_live_..." \
-H "Content-Type: application/json" \
-d '{"tier": "startup"}'

All API responses include security headers:

HeaderValuePurpose
Strict-Transport-Securitymax-age=31536000; includeSubDomainsEnforce HTTPS
X-Content-Type-OptionsnosniffPrevent MIME sniffing
X-Frame-OptionsDENYPrevent clickjacking
X-XSS-Protection1; mode=blockEnable browser XSS filter
Referrer-Policystrict-origin-when-cross-originLimit referrer leakage
Permissions-Policycamera=(), microphone=(), geolocation=()Disable unnecessary browser features

  1. Check the error message — BaseID returns specific error text, not generic codes
  2. Verify your API key — ensure it starts with bsk_live_ and hasn’t been revoked
  3. Check permissions — use GET /v1/auth/me to see your current role and permissions
  4. Check quotas — use GET /v1/admin/usage to see remaining capacity
  5. Use the Playground — the console’s API Playground lets you test requests interactively