Skip to main content
The Orchestration API is the v1 external surface for automation tools (Airflow, Dagster, CI/CD, custom schedulers). Use it to start syncs and backfills, poll job status, fetch results, and manage webhook subscriptions.
Authenticate every request with a Bearer API key in the Authorization header.

Base URL and versioning

https://api.planasonix.com
Orchestration routes live under /api/v1. Example: POST https://api.planasonix.com/api/v1/connections/{connectionId}/sync.

Trigger a sync job

POST /api/v1/connections/{connectionId}/sync
Starts an incremental sync for the given connection. The response includes a job you can poll.
connectionId
string
required
Connection identifier (for example conn_01jq8k2m3n4p5q6r7s8t9u0v1).
Request body (optional)
{
  "pipeline_id": "pl_01hqxyz",
  "priority": "normal",
  "metadata": {
    "triggered_by": "airflow_dag_nightly_sales",
    "dag_run_id": "scheduled__2025-03-27T02:00:00+00:00"
  }
}
Response 202 Accepted
{
  "data": {
    "job": {
      "id": "job_01jq8syncabc",
      "type": "connection_sync",
      "status": "queued",
      "connection_id": "conn_01jq8k2m3n4p5q6r7s8t9u0v1",
      "pipeline_id": "pl_01hqxyz",
      "created_at": "2025-03-27T14:22:10Z",
      "queued_at": "2025-03-27T14:22:10Z"
    }
  }
}

Trigger a backfill

POST /api/v1/connections/{connectionId}/backfill
Schedules a historical load over a time window. Large windows may shard into multiple internal jobs; the top-level backfill record tracks overall progress. Request body
{
  "start_at": "2025-01-01T00:00:00Z",
  "end_at": "2025-03-01T00:00:00Z",
  "tables": ["public.orders", "public.order_items"],
  "priority": "low",
  "metadata": {
    "reason": "post_incident_replay"
  }
}
Response 202 Accepted
{
  "data": {
    "backfill": {
      "id": "bf_01jq8bfill01",
      "connection_id": "conn_01jq8k2m3n4p5q6r7s8t9u0v1",
      "status": "running",
      "start_at": "2025-01-01T00:00:00Z",
      "end_at": "2025-03-01T00:00:00Z",
      "tables": ["public.orders", "public.order_items"],
      "progress_percent": 0,
      "created_at": "2025-03-27T14:25:00Z"
    }
  }
}

List all backfills

GET /api/v1/backfills
Query parameters (typical)
ParameterDescription
connection_idFilter by connection
statusqueued, running, completed, failed, cancelled
limitPage size (default 50, max 100)
cursorOpaque pagination cursor
Response 200 OK
{
  "data": [
    {
      "id": "bf_01jq8bfill01",
      "connection_id": "conn_01jq8k2m3n4p5q6r7s8t9u0v1",
      "status": "running",
      "start_at": "2025-01-01T00:00:00Z",
      "end_at": "2025-03-01T00:00:00Z",
      "progress_percent": 37,
      "created_at": "2025-03-27T14:25:00Z",
      "updated_at": "2025-03-27T14:28:44Z"
    }
  ],
  "meta": {
    "page": {
      "limit": 50,
      "cursor": "eyJiZiI6ImJmXzAxanE4YmZpbGwwMSJ9"
    }
  }
}

Get backfill status

GET /api/v1/backfills/{backfillId}
Response 200 OK
{
  "data": {
    "id": "bf_01jq8bfill01",
    "connection_id": "conn_01jq8k2m3n4p5q6r7s8t9u0v1",
    "status": "running",
    "start_at": "2025-01-01T00:00:00Z",
    "end_at": "2025-03-01T00:00:00Z",
    "tables": ["public.orders", "public.order_items"],
    "progress_percent": 37,
    "rows_processed": 1849200,
    "error": null,
    "job_ids": ["job_01jq8chunk01", "job_01jq8chunk02"],
    "created_at": "2025-03-27T14:25:00Z",
    "updated_at": "2025-03-27T14:28:44Z"
  }
}

List jobs

GET /api/v1/jobs
Query parameters (typical)
ParameterDescription
connection_idFilter by connection
pipeline_idFilter by pipeline
typeconnection_sync, backfill, pipeline_run, etc.
statusqueued, running, succeeded, failed, cancelled
since, untilISO 8601 bounds on created_at
limit, cursorPagination
Response 200 OK
{
  "data": [
    {
      "id": "job_01jq8syncabc",
      "type": "connection_sync",
      "status": "running",
      "connection_id": "conn_01jq8k2m3n4p5q6r7s8t9u0v1",
      "pipeline_id": "pl_01hqxyz",
      "created_at": "2025-03-27T14:22:10Z",
      "started_at": "2025-03-27T14:22:12Z"
    }
  ],
  "meta": {
    "page": { "limit": 50, "cursor": null }
  }
}

Get job status and details

GET /api/v1/jobs/{jobId}
Response 200 OK
{
  "data": {
    "id": "job_01jq8syncabc",
    "type": "connection_sync",
    "status": "running",
    "connection_id": "conn_01jq8k2m3n4p5q6r7s8t9u0v1",
    "pipeline_id": "pl_01hqxyz",
    "created_at": "2025-03-27T14:22:10Z",
    "queued_at": "2025-03-27T14:22:10Z",
    "started_at": "2025-03-27T14:22:12Z",
    "finished_at": null,
    "duration_seconds": null,
    "metrics": {
      "rows_extracted": 45210,
      "rows_loaded": 44802,
      "bytes_read": 67108864
    },
    "error": null
  }
}

Get job results

GET /api/v1/jobs/{jobId}/results
Returns summary result payloads after the job reaches a terminal state. While running, the API may return 409 Conflict or a partial stub depending on deployment policy. Response 200 OK
{
  "data": {
    "job_id": "job_01jq8syncabc",
    "status": "succeeded",
    "tables": [
      {
        "name": "public.orders",
        "rows_loaded": 44802,
        "checksum": "sha256:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"
      }
    ],
    "warnings": [
      {
        "code": "column_type_widened",
        "message": "Column discount_pct coerced from NUMERIC(5,2) to NUMERIC(8,4)"
      }
    ]
  }
}

Cancel a running job

POST /api/v1/jobs/{jobId}/cancel
Idempotent for already-terminal jobs: returns the current job state. Response 200 OK
{
  "data": {
    "id": "job_01jq8syncabc",
    "status": "cancelling",
    "cancel_requested_at": "2025-03-27T14:30:00Z"
  }
}

Webhooks

Manage outbound webhook subscriptions for job lifecycle and orchestration events.

List webhook subscriptions

GET /api/v1/webhooks
Response 200 OK
{
  "data": [
    {
      "id": "wh_01jq8hook01",
      "url": "https://hooks.slack.com/services/T000/B000/XXXXXXXX",
      "events": ["job.succeeded", "job.failed", "backfill.completed"],
      "enabled": true,
      "created_at": "2025-03-20T09:00:00Z"
    }
  ]
}

Create webhook subscription

POST /api/v1/webhooks
Request body
{
  "url": "https://api.internal.example.com/planasonix/webhook",
  "events": ["job.succeeded", "job.failed"],
  "secret": "whsec_custom_optional_if_server_generates"
}
Response 201 Created
{
  "data": {
    "id": "wh_01jq8hook02",
    "url": "https://api.internal.example.com/planasonix/webhook",
    "events": ["job.succeeded", "job.failed"],
    "signing_secret": "whsec_01jq8secretxxxxxxxxxxxxxxxx",
    "enabled": true,
    "created_at": "2025-03-27T15:00:00Z"
  }
}
Verify deliveries using the X-Planasonix-Signature header (HMAC over the raw body with your signing secret). Store signing_secret in your vault immediately; it may not be returned on later GET calls.

Get webhook details

GET /api/v1/webhooks/{id}
Response 200 OK
{
  "data": {
    "id": "wh_01jq8hook02",
    "url": "https://api.internal.example.com/planasonix/webhook",
    "events": ["job.succeeded", "job.failed"],
    "enabled": true,
    "last_delivery_at": "2025-03-27T14:55:01Z",
    "failure_count_24h": 0,
    "created_at": "2025-03-27T15:00:00Z"
  }
}

Update webhook

PUT /api/v1/webhooks/{id}
Request body
{
  "url": "https://api.internal.example.com/v2/planasonix/webhook",
  "events": ["job.succeeded", "job.failed", "backfill.completed"],
  "enabled": true
}
Response 200 OK
{
  "data": {
    "id": "wh_01jq8hook02",
    "url": "https://api.internal.example.com/v2/planasonix/webhook",
    "events": ["job.succeeded", "job.failed", "backfill.completed"],
    "enabled": true,
    "updated_at": "2025-03-27T15:05:00Z"
  }
}

Delete webhook

DELETE /api/v1/webhooks/{id}
Response 204 No Content

Rotate signing secret

POST /api/v1/webhooks/{id}/rotate-secret
Response 200 OK
{
  "data": {
    "id": "wh_01jq8hook02",
    "signing_secret": "whsec_01jq8newsecretyyyyyyyyyyyyy",
    "rotated_at": "2025-03-27T15:10:00Z"
  }
}

Send test event

POST /api/v1/webhooks/{id}/test
Request body (optional)
{
  "event": "job.succeeded"
}
Response 202 Accepted
{
  "data": {
    "delivery_id": "whd_01jq8test01",
    "status": "pending"
  }
}

List delivery history

GET /api/v1/webhooks/{id}/deliveries
Response 200 OK
{
  "data": [
    {
      "id": "whd_01jq8del001",
      "event": "job.succeeded",
      "status": "delivered",
      "http_status": 200,
      "attempt": 1,
      "delivered_at": "2025-03-27T14:55:01Z"
    },
    {
      "id": "whd_01jq8del002",
      "event": "job.failed",
      "status": "failed",
      "http_status": 503,
      "attempt": 3,
      "last_error": "connection reset by peer",
      "delivered_at": null
    }
  ]
}

OpenAPI specification

GET /api/v1/openapi.yaml
Returns the OpenAPI 3 document describing this v1 orchestration surface. Use it with codegen tools or import into Postman. Response 200 OK Content-Type: application/yaml with the full specification body.

Authentication

Bearer tokens and scopes.

Webhooks (product)

Event types and UI configuration.