Management API.
Everything the console does is an HTTP call. Create a key, send it as a bearer token, and drive pipelines from CI or your own tools.
Authenticate
In the console, open API keys and create one. The token starts with pgcdc_ and is shown once — copy it then. Send it on every request as Authorization: Bearer pgcdc_….
A key acts with member rights in its workspace: it can manage pipelines and destinations, but not billing or the organisation. Requests are limited to 50 per second per workspace by default; above that you get a 429.
curl -s https://app.waltail.com/api/pipelines \
-H "Authorization: Bearer pgcdc_…"
Endpoints
| Method and path | What it does |
|---|---|
POST /api/sources/check | Run the six connection checks against a connection string |
POST /api/sources/tables | List tables, with whether each can replicate and its replica identity |
POST /api/sinks/check | Live-check a destination type and config |
POST /api/pipelines | Create a pipeline: sets up the publication and slot, adds destinations |
GET /api/pipelines, GET /api/pipelines/{id} | List and read pipelines with per-destination counters |
PATCH /api/pipelines/{id} | Rename, or set state running / paused |
DELETE /api/pipelines/{id} | Drop the slot and publication, then delete |
GET /api/pipelines/{id}/tables, PUT …/tables | Read or replace the pipeline's table set |
POST /api/pipelines/{id}/backfills/estimate | Rows and bytes a backfill of the given tables would deliver |
POST /api/pipelines/{id}/backfills, GET …/backfills | Start a backfill ({"tables":[…],"confirm":true}); list jobs with per-table progress |
POST /api/backfills/{id}/cancel | Stop a running backfill |
POST /api/pipelines/{id}/sinks | Add a destination to a running pipeline |
PATCH /api/sinks/{id}, DELETE /api/sinks/{id} | Change a destination's name, batch size, rate limit or config; remove it |
GET /api/pipelines/{id}/messages | Message explorer: paged, filter by table, state and time |
GET /api/pipelines/{id}/activity, …/traffic | Captured count and latest event; delivered and failed per minute, per destination |
GET /api/sinks/{id}/undelivered | Parked messages with payload, attempts and last error |
GET /api/sinks/{id}/messages/{seq}/history | Every attempt for one message |
POST /api/sinks/{id}/replay | Requeue undelivered — {"seq":N} for one, empty body for all |
POST /api/sinks/{id}/replay-delivered | Re-deliver a {from,to} range inside the replay window |
GET /api/usage | Egress by hour, day, week, month or month-to-date, per pipeline and destination |
GET /api/plan | The workspace's plan, retention and replay window |
POST /api/keys, GET /api/keys, DELETE /api/keys/{id} | Manage API keys |
Example: create a pipeline
curl -s https://app.waltail.com/api/pipelines \
-H "Authorization: Bearer pgcdc_…" \
-H "Content-Type: application/json" \
-d '{
"name": "orders",
"source_dsn": "postgres://waltail:…@db.example.com:5432/app",
"tables": ["public.orders", "public.invoices"],
"sinks": [{
"name": "orders-webhook",
"type": "webhook",
"config": {"url": "https://example.com/hooks/waltail", "secret": "…"},
"batch_size": 50
}]
}'
The destination type values are the kinds listed on each destination page (webhook, kafka, sqs, sns, eventbridge, kinesis, s3, redis, redis_string, pubsub, elasticsearch, opensearch, typesense, meilisearch, nats, rabbitmq, eventhubs, servicebus, cloudflare_queues), and the config keys are the field names in each page's configuration table.