Three requests to a working upload flow: authenticate, upload, confirm.
Every request carries a bearer token scoped to one project.
curl https://api.guard-4.roomul.com/v2/upload/8a3f1c5b \ -H "Authorization: Bearer sk_live_••••••••" \ -H "Idempotency-Key: 7c1e-attempt-1" \ --data-binary @export.csv
A 200 means the bytes are accepted and validated — not yet durably stored. Wait for the webhook, or poll the file id, before treating the upload as final.
| Status | Meaning |
|---|---|
| 200 | Accepted and passed validation |
| 202 | Accepted, large file queued for chunked processing |
| 409 | Idempotency key reused with a different payload |
| 413 | File exceeds the plan's size limit |
| 422 | Content type not on the project's allow-list |
Register a webhook once, and every future upload notifies it — no polling required in steady state.
{
"event": "file.stored",
"id": "up_9f1kd2a",
"region": "eu-central",
"signature": "t=1727,v1=91cf…"
}
Limits apply per project, not per API key, and scale automatically with your plan.
| Plan | Sustained | Burst |
|---|---|---|
| Starter | 50 req/s | 200 req/s for 10s |
| Growth | 400 req/s | 1,200 req/s for 10s |
| Scale | Custom | Custom |