Pagination & rate limits

Pagination

Most list endpoints return a counting paginator: the items in data, page URLs in links, and page counts in meta. The shape is:

{
  "data": [ ... ],
  "links": {
    "first": "https://...",
    "last":  "https://...",
    "prev":  null,
    "next":  "https://..."
  },
  "meta": {
    "current_page": 1,
    "from": 1,
    "last_page": 10,
    "per_page": 20,
    "to": 20,
    "total": 200,
    "path": "https://..."
  }
}

Two endpoints use a different shape:

Query parameters

ParameterDefaultNotes
page11-indexed page number.
per-page20Items per page. Maximum 100.
sortnewestWhere supported: newest, oldest, priority.

Rate limits

Every API request first passes a global limiter, and a few sensitive routes add a stricter one on top. All limiters are keyed off the client IP, not the access token, so a high-traffic single host will hit the limit even with a valid token.

LimiterDefaultApplies to
api.global 300 req / 1 min Every API endpoint
api.register 10 req / 1 min /v1/auth/registration/*
api.email_verification 5 req / 1 min /v1/auth/verification/*

How a throttled request looks

HTTP/1.1 429 Too Many Requests
Retry-After: 47
X-RateLimit-Limit: 5
X-RateLimit-Remaining: 0
Content-Type: application/json

{
  "message": "Too Many Attempts."
}

The standard advice applies: back off using the Retry-After header, do not hammer the endpoint, and consider queueing requests client-side when you would otherwise approach the limit.

Configuring limits

Each limiter reads its max_attempts and decay_minutes from environment variables, defaulting to the values above:

API_RATE_LIMIT_GLOBAL=300,1
API_RATE_LIMIT_REGISTER=10,1
API_RATE_LIMIT_EMAIL_VERIFICATION=5,1

Idempotency

The API does not yet honor Idempotency-Key headers. POSTs that you want to make safe to retry (for example, POST /v1/conversation/{id}/reply) should be guarded client-side with a deduplication layer keyed off your internal message ID.