Backfill history

Re-deliver a content type's history for a Connected Profile as ordinary content events.

Events start flowing when a profile is connected, so a new profile's inbox starts empty. A backfill request re-delivers what the provider still has — as the same content.{contentType}.created events your destination already handles. Use it to seed a newly connected profile, or to recover a window after your receiver was down.

Nothing is stored: Koil pages through the provider and emits each item. Event ids are derived from the item, so an item a poll or webhook already delivered, or one re-sent by a second backfill, arrives with the id you already have: deduplicating on the event id drops it. A backfill re-delivers items that still exist; it does not replay edits or deletions.

Submit

Each item is one content type on one Connected Profile. The content type must support backfill — its provider page says which do, and GET /v1/connected-profiles/{connectedProfileId}/capabilities answers for one profile.

curl -X POST "https://api.koil.co/v1/backfill-requests" \  -H "Authorization: Bearer $KOIL_API_KEY" \  -H "Content-Type: application/json" \  -H "Idempotency-Key: $(uuidgen)" \  -d '{  "items": [    {      "connectedProfileId": "cp_123",      "contentType": "instagram.media.items"    },    {      "connectedProfileId": "cp_123",      "contentType": "instagram.stories.items"    }  ],  "since": "2026-06-01T00:00:00Z",  "maxItems": 1000}'
  • since bounds the oldest item emitted, for every item.
  • maxItems caps each item's run, not the batch.
  • Validation is atomic: an unknown, unsupported, or duplicate item rejects the whole submission with every problem named, and nothing starts.
  • Only one run per content type per profile may be in flight. A colliding submission is refused with 409 conflict, listing the in-flight backfillRequestIds in meta.conflicts; poll those instead.
  • After validation each item runs independently with its own bf_… entry, returned with 202 Accepted. An item that could not start comes back failed with an error; the others proceed.

Track

GET /v1/backfill-requests/{backfillRequestId} reports a run's progress (emitted, fetched, skipped) and status. A run finishes completed, or partial when it spent maxItems with history left; stopReason says whether it ended because the provider had nothing more (exhausted), it reached since (reached_since), or it hit the cap (capped).

The full request and response schemas are in the API endpoints reference.

On this page