Skip to main content
The RevDesk v1 API follows a consistent shape across every endpoint. The conventions on this page apply everywhere, so you can write your client code once and reuse the patterns.

Errors

Every error response uses the same envelope:
{
  "error": {
    "code": "validation_error",
    "message": "caller_id must be E.164 format",
    "fields": {
      "caller_id": "Expected +<country><number>"
    }
  }
}

Error codes

CodeHTTP statusDescription
validation_error400Request body or parameters are invalid
unauthorized401Missing or invalid API key
forbidden403API key does not have access to this resource
not_found404The requested resource does not exist
idempotency_conflict409A request with this Idempotency-Key already succeeded with a different body
caller_id_not_verified422The caller ID is not verified for your account
internal_error500An unexpected server error occurred
When a request fails validation, the fields map contains a per-field explanation so you can surface the right error next to the right input.

Idempotency

Every POST, PUT, PATCH, and DELETE endpoint supports the Idempotency-Key header. Set it to a unique value (a UUID is recommended) on your first request, and retry the same request with the same header to safely replay.
curl -X POST https://api.revdesk.com/v1/calls \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Idempotency-Key: 9b8cfa7a-1c2d-4a88-b3c0-1d2e3f4a5b6c" \
  -H "Content-Type: application/json" \
  -d '{"caller_id": "+14155551234", "destination": "+14155556789"}'

Semantics

  • First request with a key. We run the handler and persist the response under the key.
  • Repeat with the same key and same body. We replay the saved response verbatim, including status code. The replay carries an Idempotency-Replay: true response header so you can tell.
  • Repeat with the same key but a different body. We return 409 idempotency_conflict with the original key’s request id in fields.conflicts_with.

TTL

Idempotency records live for 24 hours after the first successful response. After the window, reusing the key is treated as a fresh request.

Best practices

  • Use a new key for each new logical operation. Reusing keys across different calls drops traffic.
  • The key is scoped to the API key it was submitted under. Rotating keys resets the idempotency window.
  • Idempotency only protects the RevDesk side. Don’t rely on it for cross-process transactions (for example, a call placed plus a Stripe charge).

When to set one

  • Retrying a request after a network timeout — critical.
  • Background jobs that may re-run after a worker crash — critical.
  • Interactive UIs with a double-click-vulnerable button — nice to have.
Client SDKs generate idempotency keys automatically on mutations. Set yours manually only if you need to correlate retries across a longer window than the SDK’s in-memory dedupe.

Pagination

Every list endpoint returns the same envelope:
{
  "data": [ /* items */ ],
  "meta": {
    "cursor": "opaque-string",
    "total_results": 42,
    "page_size": 20
  }
}
Pass ?cursor=<meta.cursor> on the next request to walk to the next page. meta.cursor is omitted on the last page. Cursors are opaque to clients — treat the value as a bag of bytes, do not parse it.

Example

# First page
curl "https://api.revdesk.com/v1/calls?limit=50" \
  -H "Authorization: Bearer $KEY"

# Next page
curl "https://api.revdesk.com/v1/calls?limit=50&cursor=eyJpZCI6MTIzfQ" \
  -H "Authorization: Bearer $KEY"

Limits

  • limit default is 20, max 100.
  • Cursors are valid for 24 hours from issuance. Requesting an expired cursor returns 400 validation_error with fields.cursor.
  • Ordering is by creation time, newest first for every list endpoint. Use ?order=asc where supported to reverse.