Rate limits & idempotency
Idempotency
Section titled “Idempotency”Send an Idempotency-Key header on a POST to make it safe to retry. Use a fresh, unique value
per operation (a UUID, or an id from your own system such as onboarding-8841): 1 to 255 printable ASCII
characters.
curl https://bonafide-api.republic.global/v1/envelopes \ -H "Authorization: Bearer $BONA_FIDE_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: 6f1c2f0e-1d0b-4c2a-9a59-3f1f1c7d2b11" \ -d @envelope.json- The first request with a key runs normally and its response is stored for 24 hours.
- A retry with the same key and the same request (method, path, query and body) gets the stored response
replayed, with the header
Idempotent-Replayed: true. - The same key with a different request is a
422 idempotency-key-reused. - A retry while the first request is still running is a
409 idempotency-in-progress; retry a moment later. 5xxresponses are not stored, so a retry after a server error runs again.
Keys are scoped to the caller: the organization and the API key (or dashboard user) that sent them. Operations
that take a key are marked with an Idempotency-Key header parameter in the API reference,
among them creating templates, uploading files, publishing, creating and voiding envelopes, resending links,
minting signing sessions, creating signing links and webhook endpoints, and redelivering events.
De-duplication by your own id
Section titled “De-duplication by your own id”Idempotency keys protect retries of one request. To make sure a business object is only ever sent once, also
send your own id and dedupeOn:
{ "template": "tpl_…", "externalId": "user_8841", "dedupeOn": "external_id", "…": "…" }If an envelope with that externalId already exists (in the same mode), POST /v1/envelopes returns it with
200 and x-deduplicated: true instead of creating another one. This holds across keys, days and concurrent
requests.
Rate limits
Section titled “Rate limits”The authenticated API (API keys) has no fixed request-rate limit today; sending is bounded by your plan. Limits apply where abuse is possible:
| Where | Limit |
|---|---|
POST /v1/public/verify |
60 requests per minute per IP |
GET /v1/public/anchors…, /.well-known/bona-fide/* |
240 requests per minute per IP |
GET /v1/sso/discover |
30 lookups per minute per IP |
| Signer one-time codes | 5 codes per 15 minutes per session; 5 attempts per code |
| Recipient resend | Once a minute per recipient |
| Always-on links | Per link: perEmailPerDay (default 3), perIpPerHour (default 20), optional dailyCap |
Limited public endpoints send RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset (seconds) headers.
Over the limit, the API answers 429 with a rate-limited problem, usually with a
Retry-After header in seconds.