Documentation Index
Fetch the complete documentation index at: https://docs.qflowhub.io/llms.txt
Use this file to discover all available pages before exploring further.
Rate limits
All limits are enforced at the edge (Cloudflare) and apply per source IP.
| Scope | Limit | Action on excess |
|---|
Zone-wide on api.qflowhub.io/* | 1000 requests / minute | HTTP 429 Too Many Requests, 60s mitigation window |
POST /api/comms/send (specific) | 300 requests / minute | HTTP 429, applied in addition to the zone-wide limit |
Both limits apply — your request must pass both.
The lower per-endpoint limit on /api/comms/send is a safety net against runaway loops. It’s well above any realistic legitimate flow (300/min = 18,000/hour, 432,000/day). For batch flushes (e.g. first-send to a freshly imported guest list), pace your sends at ≤5/sec and you’ll never see a 429.
Bulk endpoint payload caps
| Endpoint | Cap |
|---|
POST /api/guests/{eventId} (create or upsert) | 200 records per call |
| Bulk block / unblock by ID or barcode | 200 records per call |
Larger payloads return 400 Bad Request — split your batch into chunks of 200.
Error responses
| Status | Body / error code | Meaning |
|---|
400 | (varies) | Validation error — missing required field, malformed GUID, invalid JSON |
401 | (none) | Bearer token is missing, invalid, or expired |
403 | comms_api_not_enabled | Comms API access is not enabled for your account — request via support |
403 | trust_required | Sender verification (KYC) has not been completed |
404 | (none) | EventId, templateId, attendeeId, or webhook not found, or not owned by you |
409 | domain_already_configured | Custom domain create attempted when one is already set |
409 | domain_not_verified | /activate called before any successful /verify |
422 | spam_check_failed | Template HTML contains URLs flagged as unsafe |
422 | previous_send_permanently_failed | Recipient cannot be emailed (bounced / dropped / spam-reported / unsubscribed) |
422 | sendgrid_create_failed | SendGrid rejected the domain create — see message field |
429 | rate_limit | Too many requests from this IP — see rate limits above |
500 | (varies) | Unexpected server error — retry the request, contact support if persistent |
Operational notes
- Webhook delivery latency: typically sub-second once your account is active. After a quiet period (no comms activity for several minutes), the first webhook can take up to ~1 minute due to queue polling backoff. Subsequent webhooks within that burst are near-real-time.
- Replay window: 300 seconds. If your receiver’s clock drifts more than ~5 min from ours, valid webhooks may be rejected as stale. Keep clocks NTP-synced.
- Webhook retries: if your endpoint returns 5xx, we retry with exponential backoff up to ~10 attempts. The same
X-Qflow-Webhook-Id is reused across retries — dedupe on it.
- No subscription/event-type filtering: today, all comms events go to your single webhook URL. Filter on
X-Qflow-Event on your receiver.
Versioning
This is the v1 surface. Breaking changes will be announced at least 90 days in advance via developer email + a banner in this guide. Additive changes (new event types, new optional fields) ship without notice; build your receiver to ignore unknown fields and event types.