Coldfeet
Documentation

Errors, pagination and rate limits

The conventions below hold across the whole API, so they are worth reading once rather than rediscovering per endpoint.

Errors

Every failure — validation, authorization, rate limiting, an internal fault — comes back in the same shape:

{
  "statusCode": 400,
  "error": "Bad Request",
  "message": ["fqdn must be a valid domain"],
  "requestId": "9f1c4e0a-2b7d-4a10-8f3e-6d9b2c5a7e41",
  "path": "/api/v1/tenants/t_123/domains",
  "timestamp": "2026-01-14T09:31:52.184Z"
}

message is a string for most failures and an array of strings when validation rejected several fields at once, so handle both.

requestId is the value of the X-Request-Id response header, which is set on every response, not only failures. Send your own X-Request-Id and it is honoured and echoed back — the fastest way to have an operator find your exact request in the logs is to quote that id.

Internal faults never carry a stack trace or a database message; they say "Internal server error" and nothing more. The detail is in the server's log against the same request id.

Pagination

List endpoints take page and pageSize:

GET /api/v1/tenants/{tenantId}/dashboard/logs?page=2&pageSize=100

page starts at 1. pageSize defaults to 25 on most endpoints and 50 on the message trace, and 200 is the maximum everywhere.

The envelope is the same each time:

{
  "items": [],
  "total": 0,
  "page": 1,
  "pageSize": 25,
  "pageCount": 1
}

pageCount is never zero — an empty result set reports one empty page. Iterate until page === pageCount rather than until an empty items, and expect total to move underneath you on an endpoint that new mail keeps adding to.

Rate limits

200 requests per minute. Every response carries the state of your bucket:

X-RateLimit-Limit: 200
X-RateLimit-Remaining: 187
X-RateLimit-Reset: 43

X-RateLimit-Reset is the seconds until the window rolls over. Exceeding the limit returns 429 with a Retry-After header, in seconds. Wait that long rather than retrying immediately; a retry inside the window is itself counted.

Counting is per source IP for token traffic, so several integrations behind one NAT share a bucket. Some unauthenticated endpoints are limited far more tightly — sign-in is ten attempts a minute — but none of that applies to the organization API.

Content types

Requests and responses are JSON, with two exceptions among the token-reachable endpoints: the log export returns text/csv, and the message download returns message/rfc822. Request bodies are capped at 2 MB.

Last updated

← All documentation