Skip to content

Conventions

Four things work the same way on every endpoint — pagination, idempotency, rate limits and errors. Learn them once and the rest of the API is predictable.

Pagination

Every list endpoint is cursor-paginated. Pass a limit (default 50, maximum 200); the response carries the page of results plus a next_cursor. Pass that cursor back to fetch the next page. When next_cursor is null, you have reached the end.

Request
curl -H "Authorization: Bearer jmt_..." \
  "https://rigyx.com/api/public/v1/leads?limit=50&cursor=5b2e...-uuid"
Response
{
  "data": [
    { "id": "...", "email": "[email protected]", "status": "new" }
  ],
  "next_cursor": "a1b2...-uuid"
}
Cursors are opaque — do not parse or construct them. Just send back whatever next_cursor you were given.

Idempotency

Any POST can carry an Idempotency-Key header — a unique string you choose. The first request runs normally; for 24 hours any repeat with the same key returns the original response instead of running again. Keys are scoped to (business, key, method, path).

This makes retries safe — a network timeout on a POST /leads can be retried with the same key without creating the lead twice.

curl
curl -X POST https://rigyx.com/api/public/v1/leads \
  -H "Authorization: Bearer jmt_..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: import-2026-05-22-row-001" \
  -d '{"email": "[email protected]", "company_name": "Acme"}'
Reusing a key with a different body
If you send the same Idempotency-Key with a different body, the API rejects it with 409 and code IDEMPOTENCY_KEY_MISMATCH — rather than silently doing the wrong thing. Use a fresh key per distinct operation.

Rate limits

Each token gets 60 requests per minute by default, measured over a sliding 60-second window. Every response carries your current budget:

Response headers
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 57

Exceed the limit and the request returns 429 with a Retry-After header telling you how many seconds to wait:

429 Too Many Requests
Retry-After: 12

{
  "error": "Rate limit exceeded (60 req/min). Retry after 12s.",
  "code": "RATE_LIMIT_EXCEEDED",
  "retry_after": 12
}

Errors

Every error — on any endpoint — uses the same JSON shape. A human-readable error, a stable machine-readable code, and an optional details object. Branch your code on code, never on the message text.

Error shape
{
  "error": "This token is missing the required scope: leads:write",
  "code": "INSUFFICIENT_SCOPE",
  "details": { "required_scope": "leads:write" }
}
401UNAUTHENTICATEDMissing, invalid or revoked API token.
403INSUFFICIENT_SCOPEThe token does not hold the scope this endpoint requires.
404NOT_FOUNDNo such resource — or it belongs to another business.
409IDEMPOTENCY_KEY_MISMATCHAn Idempotency-Key was reused with a different request body.
422VALIDATION_ERRORThe request body failed validation. See details.
429RATE_LIMIT_EXCEEDEDToo many requests — slow down and retry after the given delay.
500INTERNAL_ERRORAn unexpected server error. Safe to retry.
503SERVICE_UNAVAILABLEA service the endpoint depends on is briefly unavailable.
A few endpoints add operation-specific codes — for example a document generation can return GENERATION_REFUSED when the anti-hallucination guard blocks it. These follow the same shape; the endpoint reference notes them where they apply.