Docs Reference
API
Long-running requests
Requests that start work in the background, such as a workspace sync or a full workspace export, return 202 Accepted with a link to the work's status. Poll that link until it reaches a final state.
The pattern
- You send a request that starts background work.
- Kumo.io replies
202 Accepted. The response tells you where to check progress: aLocationheader, or astatusPathin the body. - You
GETthat path until the status is final.
Status paths start with /v1. Put your API base URL in front of them, the same base you used for the original request. On kumo.io that is https://kumo.io/api/tenants/<workspace-address>. See How do I authenticate to the API?
Some endpoints also answer 202 Accepted but finish the work before they reply: syncing a single source, evaluating an environment and generating a view return the finished result in the body, and Location points at the object that was created.
Start a workspace sync
POST /v1/accounts/<account-id>/workspaces/<workspace-id>/sync-runs
The reply is 202 Accepted with a Location header pointing at the new sync run, and a body like this:
{
"data": {
"workspaceSyncRunId": "…",
"memberSourceIds": ["…", "…"]
}
}
Poll the sync run:
GET /v1/accounts/<account-id>/workspaces/<workspace-id>/sync-runs/<workspace-sync-run-id>
The run's status is one of:
| Status | Final? | Meaning |
|---|---|---|
queued | No | Waiting to start. |
running | No | Reading your sources. |
finalizing | No | Combining the sources into a new revision. |
cancelling | No | Stopping after a cancel request. |
succeeded | Yes | Every source synced. |
partial | Yes | Some sources synced and some were rejected. sourceFailures lists the failures. |
failed | Yes | The sync failed. |
cancelled | Yes | The sync was cancelled. |
The run also reports how many sources were expected, completed, accepted, rejected or partial, and when it was created, started and completed.
A workspace runs one sync at a time. Starting another while one is active returns 409 SYNC_RUN_IN_PROGRESS. Starting one sooner than your plan allows returns 429 RATE_LIMITED with a message that says how long to wait. See plans and limits.
Export or import a whole workspace
A full workspace export runs as a background job:
POST /v1/accounts/<account-id>/workspaces/<workspace-id>/export/workspace.zip/jobs
{
"data": {
"jobId": "…",
"statusPath": "/v1/accounts/…/workspaces/…/jobs/…",
"downloadPath": "/v1/accounts/…/workspaces/…/export/jobs/…/download"
}
}
Poll statusPath. When the job has succeeded, download the archive from downloadPath.
Importing into a workspace works the same way: an import job returns 202 Accepted with a jobId and a statusPath to poll.
Jobs
Every background job in a workspace can be read through the jobs endpoints:
GET /v1/accounts/<account-id>/workspaces/<workspace-id>/jobs
GET /v1/accounts/<account-id>/workspaces/<workspace-id>/jobs/<job-id>
The list is paged (see API conventions) and can be filtered with status (comma-separated) and kind.
A job has an id, a kind, a status, its progress, any failure, and timestamps (createdAt, startedAt, completedAt). Its status is one of:
| Status | Final? |
|---|---|
queued | No |
scheduled | No |
running | No |
cancelling | No |
succeeded | Yes |
failed | Yes |
cancelled | Yes |
dead_lettered | Yes: the job failed every attempt. |
A job can report succeeded with skipped: true and a skipReason when it was not run, for example because your plan doesn't include it.
Cancel or retry a job
POST /v1/accounts/<account-id>/workspaces/<workspace-id>/jobs/<job-id>/cancel
POST /v1/accounts/<account-id>/workspaces/<workspace-id>/jobs/<job-id>/retry
cancel accepts an optional {"reason": "…"}. retry works only on a job that is dead_lettered. A change the job can't make from its current state returns 409 JOB_STATE_CONFLICT.
Watch a sync live
Instead of polling, you can stream a sync run's progress as server-sent events:
GET /v1/accounts/<account-id>/workspaces/<workspace-id>/sync-runs/<workspace-sync-run-id>/diagnostics/stream
The response is text/event-stream. Each event is a data: line carrying a JSON object; comment lines keep the connection alive. If you reconnect, pass afterSeq=<the last seq you received> to continue where you left off. Send the same Authorization header as for any other request.
Polling tips
- Poll every few seconds, and back off for long-running work. Kumo.io doesn't send a recommended interval.
- Stop when the status is final, and check for
partial,failedanddead_lettered, not justsucceeded. - Store the job or run ID so you can check it again later.