Why a two-step upload
The /ingest endpoint is great for small to medium files, but Cloudflare Workers cap request bodies at 100 MB. For files up to 2 GB (Agent plan), the CLI switches to a presigned-URL flow that goes directly to R2 — bypassing the Worker entirely.
The three steps
1. POST /ingest/presign → get a time-limited R2 PUT URL
2. PUT <presign-url> → upload directly to R2
3. POST /ingest/complete → register the version, fire webhooks
# Step 1 — request a presigned URL
curl -X POST https://instadash.io/ingest/presign \
-H "Authorization: Bearer sk_live_…" \
-H "Content-Type: application/json" \
-d '{"slug":"big-export","rows":5000000,"bytes":1073741824}'
# → { "upload_url": "https://r2.cloudflarestorage.com/…", "key": "grids/…/v42.jsonl" }
# Step 2 — PUT directly to R2
curl -X PUT "<upload_url>" \
-H "Content-Type: application/x-ndjson" \
--data-binary @big-export.jsonl
# Step 3 — complete the ingest
curl -X POST https://instadash.io/ingest/complete \
-H "Authorization: Bearer sk_live_…" \
-H "Content-Type: application/json" \
-d '{"key":"grids/…/v42.jsonl","slug":"big-export","public":true}'The CLI handles this automatically
You don't need to implement the three steps yourself. The CLI checks file size and switches to presign mode automatically when the file exceeds 100 MB.
# Works the same regardless of file size
instadash push --key sk_… --name big-export --file export.jsonl
# → file is 1.2 GB — using presigned upload
# → uploading to R2… ██████████████░░░░░░ 70%
# → finalizing…
# → https://instadash.io/<handle>/big-exportPlan limits
| Plan | Max file | Max rows / push |
|---|---|---|
| Free | 10 MB | 1,000 |
| Builder | 200 MB | 100,000 |
| Agent | 2 GB | 5,000,000 |
Note: Presigned URLs expire after 15 minutes. If your upload takes longer, re-request a URL from
/ingest/presign.