documentdb icon
Request icon
Fail icon
ForEach icon
Read icon
If icon
Update icon
Insert icon
Log icon
SlackIncomingWebhook icon
Schedule icon

Ingest a public JSON API into DocumentDB

Fetch a JSON API and upsert the full feed into a DocumentDB collection daily with Kestra, with retry, idempotency, audit markers, and Slack alerts.

Categories
Data

Ingest a JSON HTTP API into Amazon DocumentDB (or any MongoDB-compatible endpoint exposed through the DocumentDB Data REST API) with a scheduled, idempotent, fully orchestrated pipeline. This blueprint fetches an entire JSON feed, validates it, and upserts every record into a DocumentDB collection keyed on a deterministic external_id, so daily runs, manual replays, and backfills overwrite documents in place instead of accumulating duplicates. It solves the classic API-to-database ingestion problem: paginating the whole feed (not just the first batch), guarding against broken upstreams, retrying transient failures, keeping the load idempotent, and recording an audit trail of every run.

How it works

  1. fetch_api (io.kestra.plugin.core.http.Request) calls the configured api_url with a GET and retries up to three times on transient errors.
  2. guard_array (io.kestra.plugin.core.execution.Fail) fails fast when the body is empty or is not a JSON array, so a broken upstream never triggers partial writes.
  3. ingest_records (io.kestra.plugin.core.flow.ForEach) iterates the full array. For each record it runs read_existing (io.kestra.plugin.documentdb.Read with fetchType: FETCH_ONE) to check for an existing document, then upsert_record (io.kestra.plugin.core.flow.If) branches to io.kestra.plugin.documentdb.Update when the document exists or io.kestra.plugin.documentdb.Insert when it does not. Because the Update task has no native upsert flag, this read-then-branch pattern emulates an upsert. The raw record is stored under a record field and ingest_count is incremented on every update.
  4. count_ingested (io.kestra.plugin.documentdb.Read with fetchType: STORE) counts the collection after the load for the run summary.
  5. insert_run_marker (io.kestra.plugin.documentdb.Insert) writes a schedule-aware audit marker to the ingestion_runs collection (source, source record count, collection size, status, execution id, schedule date).
  6. log_summary (io.kestra.plugin.core.log.Log) prints a one-line ingestion summary.

What you get

  • A full-feed load that processes every record, not just a single batch.
  • Idempotent upserts keyed on external_id, so re-runs and backfills never duplicate documents.
  • Fail-fast validation before any write touches the database.
  • Automatic retries on every HTTP and DocumentDB call.
  • A reconstructable audit trail in the ingestion_runs collection.
  • A Slack alert with the execution id when a run fails.

Who it's for

  • Data engineers loading third-party or internal JSON APIs into a document store.
  • Platform teams that need idempotent, replayable ingestion with an audit trail.
  • Anyone consolidating REST feeds into Amazon DocumentDB or a MongoDB-compatible service.

Why orchestrate this with Kestra

DocumentDB has no built-in scheduler, no feed-level orchestration, and no native upsert on its Update action. Kestra fills that gap. The io.kestra.plugin.core.trigger.Schedule trigger fires the load daily (and can be swapped for an event or webhook trigger), every task carries declarative retry policies, the errors block routes failures to Slack, and the whole pipeline is version-controlled YAML you can diff, review, and replay. The emulated upsert, fail-fast guard, and audit marker are all expressed declaratively, giving you lineage and observability that a raw cron job hitting the DocumentDB API cannot provide.

Prerequisites

  • A reachable DocumentDB Data REST API endpoint (Amazon DocumentDB or a MongoDB-compatible service that exposes the /data/v1/action/* HTTP API).
  • The target database and both collections (customers, ingestion_runs) created beforehand, or auto-created on first write by your service.
  • Each source record must contain the field named by the business_key input.
  • Outbound network access from your Kestra workers to the public API and the DocumentDB endpoint.

Secrets

  • DOCUMENTDB_HOST: base HTTPS endpoint of the DocumentDB Data REST API, for example https://your-documentdb.example.com.
  • DOCUMENTDB_USERNAME: basic-auth username for the DocumentDB API.
  • DOCUMENTDB_PASSWORD: basic-auth password for the DocumentDB API.
  • SLACK_WEBHOOK: Slack incoming webhook URL used by the failure alert.

Quick start

  1. Add the four secrets above to your Kestra instance.
  2. Adjust the database and collection variables, the api_url, and the business_key input to match your data.
  3. Run the flow manually once to validate connectivity.
  4. Run it again and confirm the collection size does not grow, proving the upsert is idempotent.
  5. Let the daily Schedule trigger take over, and create a unique index on external_id as a backstop.

How to extend

  • Replace the Schedule trigger with a webhook or Flow trigger to ingest on demand or downstream of another flow.
  • Add field-level transformations or enrichment between fetch_api and ingest_records.
  • Fan out to multiple APIs by parameterizing api_url and looping over a list of sources.
  • Push the post-load metrics from count_ingested to a monitoring or alerting destination.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.