Skip to main content

Error format

Every error response from the API returns a JSON body in this shape:
{
  "detail": {
    "message": "Human-readable description",
    "code": "machine_readable_code"
  }
}
Some errors include additional fields. For example, a tenant ceiling error includes your current usage:
{
  "detail": {
    "message": "Tenant ceiling reached. Upgrade your plan to provision more tenants.",
    "code": "tenant_limit_reached",
    "plan_name": "API Starter",
    "tenant_limit": 25,
    "connected_tenants_count": 25,
    "remaining_tenants": 0
  }
}

HTTP status codes

CodeMeaning
200Request succeeded
400Bad request — invalid payload, missing field, or constraint violation
401Authentication failed — invalid or missing API key
402Payment required — no active plan, or tenant ceiling reached
403Forbidden — you do not own the resource you are trying to access
404Not found — tenant, domain, or mailbox does not exist on your account
409Conflict — e.g. DNS not yet propagated, or domain already exists
500Internal server error — something went wrong on our side

Error codes

Authentication errors

CodeStatusDescription
invalid_auth_header401Authorization header is missing or does not start with Bearer
missing_api_key401The Bearer token is present but empty
invalid_api_key401The key does not match any active key on record
no_api_plan402Your account has no active API plan

Tenant errors

CodeStatusDescription
tenant_not_found404Tenant does not exist or belongs to a different account
tenant_limit_reached402Your plan ceiling would be exceeded by this operation

Domain errors

CodeStatusDescription
domain_not_found404Domain is not registered on this tenant
domain_limit_reached400Tenant already has 12 domains (maximum)

Mailbox errors

CodeStatusDescription
mailbox_not_found404Mailbox does not exist on this tenant
mailbox_limit_reached400Domain already has 3 mailboxes (maximum per domain)
invalid_send_limit400daily_send_limit must be between 1 and 25

Handling errors in code

import requests

response = requests.get(
    "https://api.tenantcore.io/v1/tenants",
    headers={"Authorization": "Bearer tc_live_your_key"}
)

if not response.ok:
    error = response.json().get("detail", {})
    code    = error.get("code")
    message = error.get("message")

    if code == "tenant_limit_reached":
        # Handle ceiling reached
        pass
    elif code == "no_api_plan":
        # Prompt user to purchase a plan
        pass
    else:
        raise Exception(f"API error [{response.status_code}] {code}: {message}")
const res = await fetch("https://api.tenantcore.io/v1/tenants", {
  headers: { Authorization: "Bearer tc_live_your_key" }
});

if (!res.ok) {
  const { detail } = await res.json();
  console.error(`[${detail.code}] ${detail.message}`);
}