Skip to Content
API conventions

API conventions

These rules hold across every Cloove API, so once you’ve integrated one endpoint the rest feel familiar.

Response shape

Successful responses are JSON with a consistent envelope:

{ "message": "Human-readable summary", "data": { /* the resource, or an array of resources */ }, "meta": { /* present on paginated lists */ } }
  • message - a short description, handy for logs and debugging.
  • data - the resource (object) or collection (array).
  • meta - pagination details, present only on list endpoints.

Errors

Cloove uses standard HTTP status codes. The body always includes a machine-readable error code and a human-readable message:

{ "error": "missing_scope", "message": "Missing required scope: vox:calls:create" }

Status codes

CodeMeaning
200OK
201Created
400Bad request - malformed or missing parameters
401Unauthorized - missing, invalid, or expired API key
403Forbidden - missing scope, or IP/origin not allowed
404Not found
409Conflict - duplicate or idempotency-key reuse
422Validation error - a field failed validation
429Too many requests - rate limited
5xxSomething went wrong on our side

Common error codes

errorWhen it happens
invalid_api_keyThe key is missing, malformed, or unknown
expired_api_keyThe key is past its expires_at
missing_scopeThe key lacks the scope the endpoint requires
ip_not_allowedThe request IP isn’t in the key’s allowed ranges
origin_not_allowedThe request origin isn’t in the key’s allowlist
withdrawal_policy_requiredA withdrawal was attempted without a configured key policy
idempotency_key_reusedAn Idempotency-Key was reused with a different body
request_in_progressA request with the same Idempotency-Key is still in flight

Rate limits

Limits are applied per minute. When you exceed one, Cloove returns 429 Too Many Requests with a Retry-After header (in seconds) - back off and retry after that delay.

SurfaceLimitKeyed by
Developer APIs (/v1/*)120 req / minAPI key
Public endpoints (storefront, checkout)100 req / minIP address
Portal management API (/api/developer/*)60 req / minUser

Build retry-with-backoff into your client for 429 and 5xx responses, and honor Retry-After. See best practices.

Pagination

List endpoints accept page and limit query parameters and return a meta object:

GET /v1/vox/calls?page=2&limit=20
{ "data": [ /* ... */ ], "meta": { "total": 137, "page": 2, "perPage": 20, "totalPages": 7, "hasMore": true } }

Page through results until meta.hasMore is false.

Idempotency

Network calls fail and clients retry. To make sure a retried write isn’t processed twice, send an Idempotency-Key header on POST requests that create resources (calls, orders, withdrawals, payout accounts):

Idempotency-Key: 9b2e1c7a-1f3d-4c2a-b8e1-7d6f5a4c3b2a

Use a unique value per logical operation - a UUID works well.

  • If you retry with the same key and same body, Cloove returns the original response and sets Idempotency-Replayed: true. The action runs once.
  • If you reuse a key with a different body, the request is rejected with 409 idempotency_key_reused.
  • If a request with that key is still being processed, you get 409 request_in_progress - wait and retry.

Idempotency keys are remembered for 24 hours.

Last updated on