hosting

GET /v1/site-imports/{importId}

One import job's state and progress.

All hosting endpoints

All developer docs →

Authentication

Send an API key as a bearer token. The key must carry the sites.view permission; a key without it is refused with 403, not 404.

This endpoint takes no organisation id. Your key already identifies the organisation it belongs to, and the response is scoped to it.

Try it

Replace anything in angle brackets with your own values, and the key placeholder with a key from your dashboard.

curl -X GET https://api.zinndigital.com/v1/site-imports/{importId} \
  -H "Authorization: Bearer zdk_live_…"

Signed in? The API console in your dashboard fills in your real organisation id and your own key, and runs the request against the live API so you can see the actual response. Open this endpoint in the API console

Details

A pure database read — everything reported comes from rows the workflow writes, so polling costs no archive call. Progress is per-URL counters rather than only a percentage, because "which step" is the useful answer when a customer asks why a restore is slow. budget_exhausted is surfaced deliberately: a job that stopped because it ran out of requests otherwise looks exactly like one that finished. Requires sites.view.

Parameters

NameTypeRequiredWhat it is
importId (path)UuidYesSite-import job ID (UUIDv7).

Response

NameTypeRequiredWhat it is
idUuidYesUUIDv7 identifier — sortable by creation time (docs/02 §8).
site_idstringNoThe site this import lands on, or empty. Empty is a real outcome, not an error: an aged-domain restore produces a downloadable bundle and the customer picks the target afterwards.
sourceSiteImportSourceYesWhere the content comes from. ⛔ Deliberately not the same enum as a site's source: that one records what a site was built from, for ever, while this selects a fetch strategy and…
outputSiteImportOutputYesWhat the import produces. Both are supported; neither is a default.
statusSiteImportStatusYesfetching and building are separate states rather than one running because they fail for opposite reasons and the customer's next action differs — a stall in fetching is…
status_reasonstringNoA machine code the dashboard renders through its own catalogue — never an English sentence composed by the engine, which could not be shown to the other 57 locales.
source_domainstringYes—
target_domainstringNo—
snapshot_daystringNo—
crawl_depthintegerNo—
urls_totalintegerYes—
urls_doneintegerYes—
urls_failedintegerYes—
detected_platformstringNoWhat the archived site was built on, once the crawl has seen a page — the same codes as ArchivePlatform.platform. ⛔ Empty means not established, never plain HTML; the two…
pre_restore_backup_idstringNoThe safety backup taken of the target site immediately before this restore overwrote it. ⚖️ Owner ruling 2026-09-08: a restore onto a site that already has content is gated behind…
progress_percentintegerYesFor a progress bar only. The per-URL counters are the primary display, because a percentage cannot say which step.
requests_spentintegerYes—
request_budgetintegerYes—
budget_exhaustedbooleanYesTrue when the job stopped because it ran out of requests. Surfaced deliberately — it otherwise looks identical to a job that finished, and the customer's next action depends on…
bundle_bytesintegerNo—
created_atstringYes—
started_atstringNo—
finished_atstringNo—
can_cancelbooleanYes—

Errors this endpoint can return

401 · 403 · 404 · 429