Rate limits and retries
EDFlow rate limits per bucket, the RateLimit headers, which errors to retry and how, exponential backoff with jitter, idempotency keys, and batching and size limits.
Rate limits
Token buckets, keyed by app unless stated. The platform can raise them for your app on request.
| Bucket | Applies to | Rate | Burst |
|---|---|---|---|
ingest | /v1/events*, /v1/fhir*, /v1/hl7v2, signed /ehr/v1/* (per source) | 20 requests/s | 40 |
read | GET /v1/* | 20/s | 60 |
write | Write-back and webhook management | 5/s | 20 |
sandbox | /v1/sandbox/* | 1/s | 5 |
org | Everything, per organization | 100/s | 200 |
oauthToken | /oauth/token per client | 30/min | 30 |
A busy ED produces tens of events per minute, so these limits are for backfills and runaway loops, not normal traffic.
Every response carries the IETF headers:
RateLimit-Policy: "read";q=60;w=3
RateLimit: "read";r=47;t=1q is the bucket size and w the seconds to refill it; r is what's left and t the seconds until at least one more request is allowed. A 429 has Retry-After.
Retry or not
| Response | Retry? | First |
|---|---|---|
5xx, network error, timeout (use 30 s) | Yes | Backoff |
429 | Yes | Wait Retry-After |
401 token_expired | Yes | Get a new token |
401 timestamp_out_of_window, delivery_replayed | Yes | Re-sign (same event ids) |
409 idempotency_in_progress | Yes | Wait a moment |
Per-event processing_error | Yes | Resend that event (same id) |
Any other 4xx, per-event retryable: false | No | Fix something first |
Backoff
Exponential, starting at 1 s, doubling, capped at 300 s, with ±20% jitter. Keep retrying for up to 72 hours, then dead-letter locally and alert. Transient failures are always 503 or 429 with Retry-After, on every path, including raw HL7 (never an AR).
Idempotency
- Events are idempotent by
(source, event id)for 30 days. A retry with the same ids is always safe. - Other writes (write-back, webhook management, sandbox operations) require an
Idempotency-Keyheader (1–255 characters; a UUID is recommended; never patient data). Keys last 24 hours.- Same key while the first is still running:
409 idempotency_in_progress. - Same key with a different request:
422 idempotency_key_reused. - Completed: the stored response is replayed with
Idempotent-Replayed: true. - Errors before the handler ran (authentication, validation, 429) release the key so you can fix the request and retry with the same key.
- Same key while the first is still running:
Ordering
Send each feed through a single-threaded queue so events for a visit arrive roughly in order. EDFlow doesn't depend on it: events are applied by precedence, and events within one batch in array order.
Size and count limits
| Limit | Value |
|---|---|
| Request body | 512 KiB (HL7 JSON mode: 13 MiB) |
POST /v1/events | 1 event, 32 KiB |
POST /v1/events/batch | 1–100 events |
| FHIR Bundle | 200 entries |
| HL7 | JSON mode 50 messages; raw mode 1; each 256 KiB |
List limit | 100 |
| Webhook endpoints | 20 per app, 50 per organization per environment |
| Apps | 50 per organization per environment |
| Credentials per app | 2 client secrets, 10 API keys, 5 public keys |
| IP allowlist | 50 CIDR entries |
| Roster entries | 1,000 |
Related
Dernière mise à jour le
Cette page vous a-t-elle été utile?
Errors
Every EDFlow error code: request-level HTTP status on the signed ingest profile, per-event result codes, and REST API problem details (RFC 9457) with retryable flags and the retry action to take first.
Versioning and deprecation
How the EDFlow API and event contract are versioned: the URL major version, dated Api-Version pins, specVersion, notice periods for new enum values and event types (60 days) and breaking changes (12 months), Deprecation and Sunset headers, and host migration.