Skip to main content

Rate Limiting & Pagination

Rate limiting

Nexus API endpoints are subject to rate limits to protect system stability.

TierLimitScope
Standard100 requests/minutePer user per organization
Webhook receivers500 requests/minutePer source IP
Bulk operations20 requests/minutePer user per organization

When a rate limit is exceeded, the API returns HTTP 429 Too Many Requests with a Retry-After header indicating how many seconds to wait.

HTTP/1.1 429 Too Many Requests
Retry-After: 30
Content-Type: application/json

{"error": "rate_limit_exceeded", "message": "Too many requests. Retry after 30 seconds."}

Pagination

PostgREST (database) endpoints

PostgREST endpoints use range-based pagination with the Range header:

curl https://<project-ref>.supabase.co/rest/v1/customers \
-H "Authorization: Bearer <token>" \
-H "apikey: <anon-key>" \
-H "Range: 0-24"

The response includes a Content-Range header:

Content-Range: 0-24/1523

Alternatively, use query parameters:

?offset=0&limit=25

Default page size is 25 items. Maximum page size is 100 items.

Edge Function endpoints

Edge Functions that return lists use a consistent JSON envelope:

{
"data": [...],
"pagination": {
"page": 1,
"per_page": 25,
"total": 1523,
"total_pages": 61
}
}

Use ?page=2&per_page=25 query parameters to navigate pages.

Ordering

PostgREST supports ordering via the order query parameter:

?order=created_at.desc

Multiple columns:

?order=status.asc,created_at.desc

Filtering

PostgREST supports rich filtering:

OperatorMeaningExample
eqEquals?status=eq.active
neqNot equals?status=neq.deleted
gtGreater than?total_amount=gt.100
gteGreater or equal?created_at=gte.2025-01-01
ltLess than?total_amount=lt.1000
likePattern match?name=like.*acme*
inIn list?status=in.(active,pending)
isIs null/true/false?deleted_at=is.null

Error format

All API errors follow a consistent format:

{
"error": "error_code",
"message": "Human-readable description of the error.",
"details": {}
}

Common HTTP status codes:

CodeMeaning
200Success
201Created
400Bad request (validation error)
401Unauthorized (missing or invalid token)
403Forbidden (insufficient permissions)
404Not found
409Conflict (duplicate)
429Rate limited
500Internal server error