API rate limits and uptime expectations
Before you integrate the public REST API or subscribe to outbound webhooks, this is the operational profile to plan against.
Per-key rate limit
Per-endpoint budgets vary - see the table below; for general integration code default to 60 requests per minute per API key as the safest plan-for value. Every bucket uses a sliding 60-second window. The public API reference has the full per-endpoint table:
- Most read/write endpoints (
/rulesetc.): 120/min /analytics: 30/min (queries can scan up to 90 days of stats)/eventsingest: 60/min/campaigns/import: 10/min (each request can create up to 50 campaigns)
The same sliding-60s window applies to outbound webhook signature verification on your side - if your receiver is being hit faster than 60/sec by a single Valotrix Cart Rewards delivery batch, you're being attacked, not legitimately called.
What happens on 429
When a request exceeds the bucket:
HTTP/1.1 429 Too Many Requests
Retry-After: 47
Content-Type: application/json
{ "error": "Rate limit exceeded" }
The Retry-After header is in seconds. Use it. Standard exponential-backoff-with-jitter is the recommended client behavior:
- Wait
Retry-Afterseconds. - Add random jitter (0-50%) to avoid thundering herds.
- If you 429 again, double the next wait time, up to a 5-minute ceiling.
- After 5 consecutive 429s, alert your team - something is wrong.
The X-Request-Id header on every response is your trace handle if you need to email support.
What happens on 5xx
Two surfaces, two behaviors:
Inbound API calls (your code → Valotrix Cart Rewards): 5xx is rare but possible (Render restart, database failover, Sentry-reported transient bug). Treat as a transient failure - retry with the same exponential-backoff-and-jitter pattern as 429. If you 5xx five times in a row on the same endpoint, alert.
Outbound webhooks (Valotrix Cart Rewards → your endpoint): we retry 5 times with an exponential schedule. The full delay ladder lives in app/services/webhook-dispatcher.server.ts:35:
| Attempt | Delay |
|---|---|
| 1 | immediate |
| 2 | 5 minutes |
| 3 | 30 minutes |
| 4 | 2 hours |
| 5 | 12 hours |
Total time across all 5 attempts: ~14.5 hours. If your endpoint is down longer than that, the delivery is moved to dead-letter (see Webhook delivery SLA below).
Webhook deliveries are considered successful on any 2xx response. Anything else (4xx, 5xx, timeout, TLS error) counts as a failure and triggers the next retry.
Uptime expectations
We don't publish a formal SLA today. We're a pre-submission solo-founder app on Render and we'd rather under-promise. That said, the operational posture:
- App runs on Render with health-checked auto-restart on crash.
- Postgres backups every 6 hours (Render-managed).
- Error monitoring via Sentry with alert rules on error rate spikes.
- Solo founder is on-call EU business hours; same-day response on weekdays via
valentin@valotrix.com.
Internal target - not an SLA, just what we operate against - is "no merchant should see a multi-hour outage without communication." If an outage happens:
- An in-app banner posts to the admin home page.
- Affected merchants get an email broadcast to the address on file.
- Status updates continue until resolution; postmortem follows within 48 hours.
If you need a contractual SLA (e.g. for procurement or compliance review), email valentin@valotrix.com - we can negotiate one for Scale-plan customers.
Status page
Not live yet - we're pre-submission, no public-facing uptime history to point at.
When it ships it'll live at status.valotrix.com and will track API uptime, webhook delivery success rate, and storefront proxy availability with 90-day rolling history. Until then, email is the canonical outage channel.
Webhook delivery SLA
Best-effort. The retry schedule above (5 attempts, ~14.5h total) is our commitment for transient receiver failures. Deliveries that fail all 5 attempts move to dead-letter state in our database - they stay there indefinitely so we can replay them once you've fixed your endpoint.
To inspect dead-letter rows for your shop:
- Email
valentin@valotrix.comwith the date range and event types you want. - We'll inspect the dead-letter rows and either replay them to a fresh endpoint URL or export the JSON for you.
Self-serve dead-letter inspection in the merchant admin is on the roadmap - not shipped yet.
What's not in scope today
Documented for transparency:
- No webhook batch endpoint - each event = one HTTP call. If you subscribe to high-volume events (
gift.added,gift.removed) on a high-traffic store, your endpoint should handle ~tens of calls per minute during peak hours. - No HMAC algorithm choice - webhooks are HMAC-SHA-256 only. SHA-512 may come later.
- No replay API - to replay a failed delivery, email support.
- No webhook subscription management via REST API - endpoints are configured in Settings → Webhooks only. Programmatic subscription management is on the roadmap.