Skip to main content

Exports API

Large topology exports run as background jobs. You start a job, poll its status, and download the file when it has finished. This is currently available via the API; a UI for it is coming.

Background exports are available for the diagram and draw.io topology exports. Other exports (document preview, package bundles, remediation export) are still synchronous today.


Endpoints​

MethodPathDescriptionPermission
POST/api/v1/tenants/{tenantID}/exportsStart an export jobnodes:read
GET/api/v1/tenants/{tenantID}/exportsList export jobsnodes:read
GET/api/v1/tenants/{tenantID}/exports/{jobID}Get job statusnodes:read
GET/api/v1/tenants/{tenantID}/exports/{jobID}/downloadDownload the finished filenodes:read

These require the same permission as the existing topology export endpoints.

Artifact storage required

If artifact storage is not configured for your deployment, these endpoints return 503 with the message artifact storage not configured.


Start an Export​

POST /api/v1/tenants/{tenantID}/exports

Request Body​

{
"kind": "architecture_diagram",
"params": {}
}
FieldTypeDescription
kindstringarchitecture_diagram or drawio
paramsobjectOptional. architecture_diagram accepts {"format": "png"}; drawio takes no parameters. Unknown parameters return 400.

Response — 202 Accepted​

{
"job_id": "3f2b8c1e-5d4a-4f7e-9a21-6c0d8e7b1a54",
"status": "queued",
"status_url": "/api/v1/tenants/acme-corp/exports/3f2b8c1e-5d4a-4f7e-9a21-6c0d8e7b1a54",
"already_active": false,
"reason": ""
}

If an identical request is already queued or running, Infracast returns the existing job with "already_active": true instead of creating a duplicate.

Example​

curl -X POST https://api.infracast.io/api/v1/tenants/acme-corp/exports \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"kind": "drawio", "params": {}}'

Get Job Status​

GET /api/v1/tenants/{tenantID}/exports/{jobID}
{
"job_id": "3f2b8c1e-5d4a-4f7e-9a21-6c0d8e7b1a54",
"status": "succeeded",
"size_bytes": 4821937,
"attempts": 1,
"created_at": "2026-10-06T10:00:00Z",
"started_at": "2026-10-06T10:00:02Z",
"finished_at": "2026-10-06T10:00:41Z",
"expires_at": "2026-10-13T10:00:41Z"
}
StatusMeaning
queuedWaiting for a worker
runningBeing built
succeededFinished; ready to download
failedDid not complete; see the error field
expiredThe result was deleted after its retention period

A job whose worker stops unexpectedly is retried automatically, up to 3 attempts, then marked failed with a reason. The attempts field shows how many have been made.


List Export Jobs​

GET /api/v1/tenants/{tenantID}/exports?limit=20&offset=0
{
"items": [ { "job_id": "3f2b8c1e-5d4a-4f7e-9a21-6c0d8e7b1a54", "status": "succeeded" } ],
"total": 1,
"limit": 20,
"offset": 0,
"has_more": false
}
  • With no limit, all rows are returned. A limit you supply is never silently capped.
  • An invalid limit or offset returns 400.

Download​

GET /api/v1/tenants/{tenantID}/exports/{jobID}/download

Returns the file. Error responses:

CodeMeaning
409The job has not finished, or it failed
410The result has expired and been deleted
404Unknown job, or a job that belongs to another tenant or workspace

Finished files are kept for 7 days.


Topology Export Endpoints​

The synchronous endpoints keep working:

GET /api/v1/tenants/{tenantID}/topology/export/diagram
GET /api/v1/tenants/{tenantID}/topology/export/drawio
  • Up to 500 nodes: unchanged — the file is returned directly.
  • Above 500 nodes, when artifact storage is configured: 202 Accepted with a Location header pointing at the job status URL and a JSON body { "job_id", "status_url", "reason" }. Clients must poll the status URL and then download the result.
  • Artifact storage not configured: synchronous at every size.

Client code that calls these endpoints should therefore handle a 202 response.


Example: Start, Poll, Download​

BASE=https://api.infracast.io/api/v1/tenants/acme-corp

# 1. Start
JOB=$(curl -s -X POST $BASE/exports \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"kind": "architecture_diagram", "params": {}}' | jq -r .job_id)

# 2. Poll until finished
while true; do
STATUS=$(curl -s -H "Authorization: Bearer $TOKEN" $BASE/exports/$JOB | jq -r .status)
[ "$STATUS" = "succeeded" ] && break
if [ "$STATUS" = "failed" ] || [ "$STATUS" = "expired" ]; then echo "export $STATUS"; exit 1; fi
sleep 5
done

# 3. Download
curl -s -H "Authorization: Bearer $TOKEN" -o export.out $BASE/exports/$JOB/download

Next Steps​