Pagination, limits, and idempotency
Three mechanics every integration touches: how lists page, how fast you can call, and how to retry a create safely. All three are visible in response headers, so your client can adapt instead of guessing.
Cursor pagination
Lists return up to limit items (1 to 100, default 25) plus has_more and next_cursor. Pass the cursor back to continue; a null cursor means you're done. Cursors are opaque and signed: don't build or edit them, and don't reuse a cursor from one endpoint on another (that's a 400). New rows arriving mid-walk never duplicate or skip what you've already seen.
curl "https://fullhall.au/api/v1/contacts?limit=100" \ -H "Authorization: Bearer fh_live_..." # ... then, while has_more is true: curl "https://fullhall.au/api/v1/contacts?limit=100&cursor=eyJr..." \ -H "Authorization: Bearer fh_live_..."
Rate limits and the daily quota
Two layers. Each key can burst to 60 requests and sustain 5 a second: that's the abuse guard, and hitting it returns a 429 with code: "rate_limited". Each organisation also has 10,000 requests a day across all its keys, resetting at midnight UTC: that's the plan allowance, and exhausting it returns a 429 with code: "quota_exceeded" and a quota block naming the reset time. Both send Retry-After.
Every authenticated response carries both header styles:
RateLimit: "default";r=54;t=2 RateLimit-Policy: "default";q=60;w=12, "daily";q=10000;w=86400 X-RateLimit-Limit: 60 X-RateLimit-Remaining: 54 X-RateLimit-Reset: 1784692800
A full nightly sync of a 2,000-contact organisation costs about 20 requests, so the quota is roomy for normal use. If your integration genuinely needs more, talk to us.
Idempotency on creates
Send an Idempotency-Key header (any string up to 255 printable characters; a UUID is ideal) on any POST. If the same key and body arrive again within 24 hours, you get the original response replayed with an idempotent-replayed: true header instead of a second create. The same key with a different body is a 422; a concurrent duplicate is a 409. One caveat for file uploads: a replayed upload_url may have expired, so reserve again with a fresh key if the PUT fails.
curl -X POST https://fullhall.au/api/v1/contacts \
-H "Authorization: Bearer fh_live_..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 9f6d3c2e-…" \
-d '{"first_name": "Priya", "email": "[email protected]"}'The full endpoint-by-endpoint detail lives in the interactive reference, generated from the same code that serves the API.