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:
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. Call-failure errors additionally carry a category, a generalized bucket you can show an end user. See Errors for the full list of codes and categories, including every reason a call can fail to be placed or connect.

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.

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.

With the SDK

@revdesk/sdk takes an idempotencyKey on any mutation and sends it as the Idempotency-Key header. Use generateIdempotencyKey() or supply your own:

Pagination

Every list endpoint returns the same envelope:
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

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.

With the SDK

@revdesk/sdk handles cursors for you. list() returns one page; listAll() is an async iterator that walks every page:
listAll() is available on phoneNumbers, subEntities, and callerTrust.reputation.numbers.