Pagination & idempotency
Design resilient integrations with cursor-based pagination for high-volume collections and 24-hour idempotency keys to ensure network retries never produce duplicate posts.
Cursor-based pagination
List endpoints (such as GET /v1/posts and GET /v1/workspaces) use cursor-based pagination rather than numeric offsets. This avoids page-drift issues when new posts are scheduled while your script is reading.
Items per page (max 50)
Defaults to 20 items. You can request up to a maximum of 50 items per query. Values above 50 return 400 validation_failed.
Opaque pagination token
Pass the next_cursor string returned from the previous response page. When next_cursor is null, the end has been reached.
Pagination code example
Here is how to fetch all items across multiple pages in JavaScript and Python:
async function getAllPublishedPosts(workspaceId) { let cursor = null; const allPosts = []; do { const url = new URL("https://api.foxli.app/v1/posts"); url.searchParams.set("status", "published"); url.searchParams.set("limit", "50"); if (cursor) url.searchParams.set("cursor", cursor); const res = await fetch(url.toString(), { headers: { Authorization: `Bearer ${process.env.FOXLI_API_KEY}`, "Foxli-Workspace": workspaceId, }, }); if (!res.ok) throw new Error(`Failed to fetch posts: ${res.status}`); const json = await res.json(); allPosts.push(...json.posts); cursor = json.meta?.next_cursor || null; } while (cursor); return allPosts; }
Idempotent POST requests
Network connections can drop after a server processes an API call but before the client receives the HTTP response. To prevent accidentally creating duplicate posts, pass an Idempotency-Key header on all state-mutating requests:
- Supported on
POST /v1/posts,POST /v1/media,POST /v1/workspaces, andPOST /v1/webhooks. - Use a unique string (e.g. UUIDv4 or your internal database record ID).
- Foxli caches the resulting response body and status code for 24 hours.
- If your client retries the same request within 24 hours, Foxli returns the cached result without executing the creation again.
curl -X POST https://api.foxli.app/v1/posts \ -H "Authorization: Bearer $FOXLI_API_KEY" \ -H "Foxli-Workspace: ws_brand_primary" \ -H "Idempotency-Key: 9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d" \ -H "Content-Type: application/json" \ -d '{ "channel_ids": ["ch_ig_01"], "content": "Automated weekly update 🚀", "mode": "now" }'
Idempotency errors (409 & 422)
idempotency_in_progressReturned if a concurrent request with the identical key is already being processed. This distributed lock prevents race-condition double posting. Wait 2–3 seconds and retry.
idempotency_mismatchReturned if an Idempotency-Key was previously submitted within the last 24 hours with a different request payload. Ensure each distinct post or operation generates its own distinct UUID.