---
title: "Run sync pipeline (read → write)"
method: POST
path: "/pipeline_sync"
tags: ["Stateless Sync API"]
---

# Run sync pipeline (read → write)

`POST /pipeline_sync`

Without a request body, reads from the source connector and writes to the destination (backfill mode). With an NDJSON request body, uses the provided messages as input instead of reading from the source (push mode — e.g. piped webhook events). Alternatively, send Content-Type: application/json with {pipeline, state?, body?} to pass config in the body.

## Query parameters

- `state_limit` integer — Stop streaming after N state messages.
- `time_limit` number — Stop streaming after N seconds.

## Request body

- object
  - `pipeline` PipelineConfig, required
    - `source` SourceConfig, required
      - `type` 'stripe', required
      - `stripe` SourceStripeConfig, required
        - `api_key` string, required — Stripe API key (sk_test_... or sk_live_...)
        - `account_id` string — Stripe account ID (resolved from API if omitted)
        - `livemode` boolean — Whether this is a live mode sync
        - `api_version` '2026-03-25.dahlia' | '2026-02-25.clover' | '2026-01-28.clover' | '2025-12-15.clover' | '2025-11-17.clover' | '2025-10-29.clover' | '2025-09-30.clover' | '2025-08-27.basil' | '2025-07-30.basil' | '2025-06-30.basil' | '2025-05-28.basil' | '2025-04-30.basil' | '2025-03-31.basil' | '2025-02-24.acacia' | '2025-01-27.acacia' | '2024-12-18.acacia' | '2024-11-20.acacia' | '2024-10-28.acacia' | '2024-09-30.acacia' | '2024-06-20' | '2024-04-10' | '2024-04-03' | '2023-10-16' | '2023-08-16' | '2022-11-15' | '2022-08-01' | '2020-08-27' | '2020-03-02' | '2019-12-03' | '2019-11-05' | '2019-10-17' | '2019-10-08' | '2019-09-09' | '2019-08-14' | '2019-05-16' | '2019-03-14' | '2019-02-19' | '2019-02-11' | '2018-11-08' | '2018-10-31' | '2018-09-24' | '2018-09-06' | '2018-08-23' | '2018-07-27' | '2018-05-21' | '2018-02-28' | '2018-02-06' | '2018-02-05' | '2018-01-23' | '2017-12-14' | '2017-08-15'
        - `base_url` string, uri — Override the Stripe API base URL (e.g. http://localhost:12111 for stripe-mock)
        - `webhook_url` string, uri — URL for managed webhook endpoint registration
        - `webhook_secret` string — Webhook signing secret (whsec_...) for signature verification
        - `websocket` boolean — Enable WebSocket streaming for live events
        - `poll_events` boolean — Enable events API polling for incremental sync after backfill
        - `webhook_port` integer — Port for built-in webhook HTTP listener (e.g. 4242)
        - `revalidate_objects` string[] — Object types to re-fetch from Stripe API on webhook (e.g. ["subscription"])
        - `backfill_limit` integer — Max objects to backfill per stream (useful for testing)
        - `max_concurrent_streams` integer — Max streams paginating in parallel (default: 5, capped at catalog size).
    - `destination` union, required
      - object
        - `type` 'postgres', required
        - `postgres` DestinationPostgresConfig, required
          - `url` string — Postgres connection string (alias for connection_string)
          - `connection_string` string — Postgres connection string
          - `host` string — Postgres host (required for AWS IAM)
          - `port` number — Postgres port
          - `database` string — Database name (required for AWS IAM)
          - `user` string — Database user (required for AWS IAM)
          - `schema` string, required — Target schema name (e.g. "stripe_sync")
          - `batch_size` number — Records to buffer before flushing
          - `aws` object — AWS RDS IAM authentication config
            - `region` string, required — AWS region for RDS instance
            - `role_arn` string — IAM role ARN to assume (cross-account)
            - `external_id` string — External ID for STS AssumeRole
          - `ssl_ca_pem` string — PEM-encoded CA certificate for SSL verification (required for verify-ca / verify-full with a private CA)
      - object
        - `type` 'google_sheets', required
        - `google_sheets` DestinationGoogleSheetsConfig, required
          - `client_id` string — Google OAuth2 client ID (env: GOOGLE_CLIENT_ID)
          - `client_secret` string — Google OAuth2 client secret (env: GOOGLE_CLIENT_SECRET)
          - `access_token` string, required — OAuth2 access token
          - `refresh_token` string, required — OAuth2 refresh token
          - `spreadsheet_id` string — Target spreadsheet ID (created if omitted)
          - `spreadsheet_title` string — Title when creating a new spreadsheet
          - `batch_size` number — Rows per Sheets API append call
    - `streams` object[]
      - `name` string, required — Stream (table) name to sync.
      - `sync_mode` 'incremental' | 'full_refresh' — How the source reads this stream. Defaults to full_refresh.
      - `fields` string[] — If set, only these fields are synced.
      - `backfill_limit` integer — Cap backfill to this many records, then mark the stream complete.
  - `state` SyncState — Full sync checkpoint with separate sections for source, destination, and engine. Connectors only see their own section; the engine manages routing.
    - `source` object, required — Source connector state — cursors, backfill progress, events cursors.
      - `streams` object, required — Per-stream checkpoint data, keyed by stream name.
      - `global` object, required — Section-wide state shared across all streams.
    - `destination` object, required — Destination connector state — reserved for future use.
      - `streams` object, required — Per-stream checkpoint data, keyed by stream name.
      - `global` object, required — Section-wide state shared across all streams.
    - `engine` object, required — Engine-managed state — cumulative record counts, sync metadata not owned by connectors.
      - `streams` object, required — Per-stream checkpoint data, keyed by stream name.
      - `global` object, required — Section-wide state shared across all streams.
  - `body` unknown[]
    - unknown

## Response `200`

NDJSON stream of sync messages

## Other responses

- `400` — Invalid params

## Changes

- **2026-04-17** `22f29cb9e680` — 6 warning, 5 info
  - removed the request property `pipeline/source/oneOf[subschema #1]/stripe/rate_limit`
  - removed the optional property `oneOf[#/components/schemas/ControlMessage]/control/oneOf[subschema #1]/source_config/rate_limit` from the response with the `200` status
  - added the new `range_complete` enum value to the `oneOf[#/components/schemas/EofMessage]/eof/stream_progress/additionalProperties/status` response property for the response status `200`
  - added the new `range_complete` enum value to the `oneOf[#/components/schemas/TraceMessage]/trace/oneOf[subschema #2]/stream_status/status` response property for the response status `200`
  - …7 more
- **2026-04-15** `2ad11e01c495` — 2 info
  - added the media type `application/json` to the request body
  - the `header` request parameter `x-pipeline` became optional
- **2026-04-15** `4e5abb8c5e22` — 2 breaking
  - removed the media type `application/json` from the request body
  - the `header` request parameter `x-pipeline` became required
- **2026-04-15** `2e101196e4f5` — 2 info
  - added the media type `application/json` to the request body
  - the `header` request parameter `x-pipeline` became optional
- …earlier changes not shown

[Full history](https://skmtc.dev/stripe/apis/stripe-sync-engine/changes/pipeline_sync/post.md)

---

[API](https://skmtc.dev/stripe/apis/stripe-sync-engine.md) · [All operations](https://skmtc.dev/stripe/apis/stripe-sync-engine/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/stripe/stripe-sync-engine/revisions/22f29cb9e680/schema)
