Skip to content

Requests and responses

Every endpoint answers in the same shape, which means your integration can have one place that unwraps a response and one place that handles a failure.

A successful call:

{
"success": true,
"data": {},
"request_id": "req_abc123",
"timestamp": "2026-09-07T12:00:00Z"
}

Read success first, then data. A failure carries an error object instead — see errors.

Keep the request_id. It identifies that one call in the server’s own logs, and it is the first thing support will ask for. Store it against whatever record your system created, alongside the ID that came back.

Database IDs come back as JSON numbers, not strings — "id": 501, not "id": "501". Your own external IDs stay strings. A language that guesses types will get this right; a schema that expects strings will not.

List and lookup endpoints add a pagination block outside data:

{
"success": true,
"data": [],
"pagination": {
"index": 0,
"limit": 50,
"returned": 2,
"total": 2,
"has_more": false
},
"request_id": "req_abc123",
"timestamp": "2026-09-07T12:00:00Z"
}

Paging is optional — ask for nothing and you get the first 50.

ParameterDefaultAllowed
index0A zero-based record offset, not a page number. Non-negative.
limit501 to 200.
GET {BASE_URL}/countries?index=0&limit=50
GET {BASE_URL}/countries?index=50&limit=50

index counts records, not pages. The second call above starts at the 51st record; it is not “page 50”. This is the mistake worth checking for in your code, because passing a page number quietly returns the wrong slice rather than an error.

Use has_more to decide whether to ask again, rather than comparing counts yourself. total is how many records match altogether, not how many came back in this response — that is returned.

  • Every datetime you send must be ISO-8601 with an offset or Z2026-09-10T10:00:00+05:30 or 2026-09-10T04:30:00Z. A datetime with no zone is rejected rather than guessed at.
  • Every datetime you receive is UTC, ending in Z.

So a job scheduled for 10 a.m. in Mumbai is sent as +05:30 and comes back as 04:30:00Z. Both are the same moment; convert for display rather than storing what you were shown and treating it as local.

Fixed for every credential:

  • 60 requests per minute
  • 1000 requests per hour

Every authenticated response tells you where you stand:

X-RateLimit-Minute-Limit: 60
X-RateLimit-Minute-Remaining: 59
X-RateLimit-Minute-Reset: 1788789600
X-RateLimit-Hour-Limit: 1000
X-RateLimit-Hour-Remaining: 999
X-RateLimit-Hour-Reset: 1788789600

Exceed either and the answer is 429, with a Retry-After header in seconds:

Retry-After: 42

Wait that long and retry with the same idempotency key — see idempotency and retries. Reading the remaining counts and slowing down before you hit the wall is better than being told to stop, particularly on a nightly batch that pushes a day’s work in one go.