Pagination & Rate Limits

Cursor-based pagination and rate limiting across all API endpoints.

hookstream uses cursor-based pagination for all list endpoints and applies rate limiting to protect the platform. Understanding these patterns helps you build robust integrations that handle large datasets and respect rate limits.

Cursor-based pagination

All list endpoints return paginated results. Each endpoint uses a named wrapper key matching the resource type (e.g., sources, destinations, events, connections). To fetch the next page, pass the cursor value as a query parameter.

Cursors are opaque strings — do not parse or construct them. They remain stable across pages even when new records are inserted.

Example

bash
# First page GET /v1/sources?limit=20
json
{ "sources": [...], "cursor": "eyJpZCI6...", "has_more": true }
bash
# Next page GET /v1/sources?limit=20&cursor=eyJpZCI6...
json
{ "sources": [...], "cursor": null, "has_more": false }

Query Parameters

cursor string

Opaque cursor from a previous response. Omit for the first page.

limit number default: 20

Number of results per page. Maximum 100.

Results are ordered by creation time (newest first) unless otherwise specified on the endpoint.

Always check has_more before fetching the next page — do not assume fixed page sizes. Some endpoints (events, delivery-attempts) use different defaults and wrapper shapes; always read the actual response.

Rate limiting

Authenticated endpoints are rate-limited per organization. Unauthenticated endpoints (ingest, test sessions, tools) are rate-limited per IP address. When you exceed the rate limit, the API returns 429 Too Many Requests.

Rate limit headers

Every response includes IETF standard RateLimit-* response headers:

HeaderMeaning
RateLimit-LimitMaximum requests allowed in the current window.
RateLimit-RemainingRequests remaining in the current window.
RateLimit-ResetSeconds until the window resets.

Example:

http
RateLimit-Limit: 1000 RateLimit-Remaining: 742 RateLimit-Reset: 37

When RateLimit-Remaining reaches 0, wait until RateLimit-Reset seconds have elapsed before making additional requests.

Best practices

1

Check has_more, not cursor presence

Always check has_more to decide whether to fetch another page — some endpoints return cursor: null on the last page, others don't.

2

Back off on 429

Implement exponential backoff when receiving 429 responses. Read RateLimit-Reset for the minimum wait.

3

Tune limit to your workload

Use the limit parameter to control page size based on your processing capacity. Larger pages = fewer round trips but more latency per request.

4

Prefer WebSocket streaming for live data

For high-volume integrations, use WebSocket streaming instead of polling list endpoints.

Ask a question... ⌘I