SendaiDocs

API reference

View as Markdown

API tokens

Create, list, and revoke the API keys that authenticate every request. The key secret is returned once, at creation, and never again.

API keys are the only credential on the API. Create your first key in the dashboard under Settings → Developer; once you hold one, you can manage keys over the API itself. For rotation runbooks and safe handling, see Authentication.

There is no single canonical token object: the create response is a snake_case object carrying the secret once, while the list response serialises the internal record with PascalCase field names. Each shape is documented with its operation below rather than pretended into one.

Create an API key

POST/api/v1/api-tokens

Creates a key. data.token is the secret and is returned only here — Sendai stores a hash, so a lost key cannot be recovered; revoke it and create another.

Request body

  • namestringrequired
    Identifies the key. Name it for the service that will use it — you will be glad of it when you come to rotate.

Response

data.id is what you pass to the revoke endpoint — keep it alongside the key. account_id is the account the key authenticates as; the account-scoped Balances and Sender IDs endpoints take it in their path.

Errors

StatusWhen
400name is missing — listed in error.validation_errors.
401Missing, malformed, or revoked API key.
RequestPOST /api/v1/api-tokens
curl -X POST https://api.sendai.co.zw/api/v1/api-tokens \
  -H "Authorization: Bearer $SENDAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "orders-service" }'
Response
201 Created
{
  "status": "success",
  "message": "api token created — save this token, it will not be shown again",
  "data": {
    "id": "9f2a4c8e-6b21-4d0f-a97b-5e8c1d2f6a3b",
    "name": "orders-service",
    "token": "sk_live_4c8e6b21d0f34a97b5e8c1d2f6a3b904",
    "account_id": "2d6f4b8e-1a90-4e21-8b7d-3f1a5c2e9a0c",
    "created_at": "2026-07-06T09:12:03Z"
  }
}

List API keys

GET/api/v1/api-tokens

Lists the keys on your account. This response is not normalised: it serialises the internal record directly, so field names are PascalCase rather than snake_case and include storage columns.

Read ID, Name, Active, CreatedAt and LastUsedAt; treat everything else (such as TokenHash) as unstable and do not build against it. Key material is never returned.

LastUsedAt is the useful one for cleanup: null means never used, and a key untouched for months is usually one you can revoke.

Errors

StatusWhen
401Missing, malformed, or revoked API key.
RequestGET /api/v1/api-tokens
curl https://api.sendai.co.zw/api/v1/api-tokens \
  -H "Authorization: Bearer $SENDAI_API_KEY"
Response
200 OK
{
  "status": "success",
  "message": "",
  "data": [
    {
      "ID": "9f2a4c8e-6b21-4d0f-a97b-5e8c1d2f6a3b",
      "CreatedAt": "2026-07-06T09:12:03Z",
      "UpdatedAt": null,
      "DeletedAt": null,
      "Name": "orders-service",
      "TokenHash": "9b74c9897bac770ffc029102a200c5de0d3d2a2f4b2b6c9a2f0b4b2c1d8e3f7a",
      "AccountId": "2d6f4b8e-1a90-4e21-8b7d-3f1a5c2e9a0c",
      "Active": true,
      "LastUsedAt": "2026-08-06T11:04:19Z"
    }
  ]
}

Revoke an API key

DELETE/api/v1/api-tokens/{id}

Revokes immediately — the next request using that key gets a 401.

Path parameters

  • idstring (uuid)required
    The key's ID, from the create or list response.

Response

Note that revoking an id that does not exist does not return 404 — treat a 200 as "this key is now not valid" rather than as proof the key existed.

Errors

StatusWhen
400id is not a valid UUID.
401Missing, malformed, or revoked API key.
RequestDELETE /api/v1/api-tokens/{id}
curl -X DELETE https://api.sendai.co.zw/api/v1/api-tokens/9f2a4c8e-6b21-4d0f-a97b-5e8c1d2f6a3b \
  -H "Authorization: Bearer $SENDAI_API_KEY"
Response
200 OK
{ "status": "success", "message": "api token revoked" }