SigFollow
Sign in

Public API

Rate limiting & idempotency

A per-key fixed-window rate limit protects shared infrastructure; Idempotency-Key lets your safe retries skip the side effects you already paid for.

Per-key rate limit

Requests are counted per API key on a 1-second sliding bucket. The default ceiling is 80 requests per second; raise or lower it per key in Integrations → API Keys → Advanced. The limit applies across all endpoints — sending messages, listing templates, syncing contacts all consume from the same bucket.

When you exceed the limit:

  • HTTP 429 with Meta error code: 4
  • Response header Retry-After with the number of seconds to wait before the next attempt
  • No partial side effects — the request is rejected before reaching the business logic
Smooth bursts, then queue
Use a token bucket on your side sized to ~70% of your ceiling. That leaves headroom for retries and avoids the "fast pile up" pattern that produces alternating 200/429 noise.

Idempotency-Key

Mutation endpoints (POST, PATCH, PUT) accept an Idempotency-Key request header. SigFollow caches the response for 24 hours on the tuple (api_key.id, idempotency_key). Subsequent identical requests replay the original response without re-executing the handler.

Send a key that is reasonably unique—UUIDv4 works well:

POST /v1/PHONE_NUMBER_ID/messages HTTP/1.1
Host: api.sigfollow.com
Authorization: Bearer sflo_live_xxx
Idempotency-Key: 8c7f0c50-3d8b-4d9e-9b1a-1cb2dc1ba2b4
Content-Type: application/json

{ "messaging_product": "whatsapp", "to": "...", "type": "text", "text": { "body": "Hi" } }

The replay carries an additional response header so you can detect it:

HTTP/1.1 200 OK
Idempotency-Replayed: true
Content-Type: application/json

Rules and caveats

  • Only successful responses (2xx) are cached. Failed responses are not cached because the failure may be transient or parameter-related; you should retry without changing the key.
  • Keys are scoped per api_key.id. Two different keys with the same idempotency value do not collide.
  • Keys are not scoped per endpoint path. Reusing the same key across different endpoints will replay an earlier response—use a fresh key per logical operation.
  • During in-flight execution, the server holds a 60-second lock on (api_key.id, idemKey) to prevent double execution. A second request landing while the first is still running is rejected immediately with 409 Conflict, body { "error": "idempotency_in_flight", ... }, and the response header Retry-After: 1. The caller must back off and retry — the second request does notblock and wait for the winner's response.
When to use Idempotency-Key
Reach for it any time the network might lose your response and you still need to retry: deploy hooks, queue workers, mobile clients on flaky connections. For pure read endpoints (GET) the header is ignored—reads are naturally idempotent.

Backoff strategy

Recommended retry plan for 429 and 5xx:

attempt 1   → wait 1s
attempt 2   → wait 2s
attempt 3   → wait 4s
attempt 4   → wait 8s
attempt 5+  → wait 16s (cap)
honor Retry-After when present

Always include the same Idempotency-Key across retries, otherwise a partially-applied call (e.g. message accepted but client timed out) will produce duplicate outbound messages.