hosting

GET /v1/sites/export

Download the sites in scope as a CSV.

All hosting endpoints

All developer docs →

Authentication

Send an API key as a bearer token. The endpoint checks sites.view; a key without it is refused with 403, not 404.

Where your organisation id goes

This endpoint takes org_id as a query parameter. Leave it out and the call covers your whole tenancy subtree; send it to narrow the call to one organisation.

Your organisation id is on the API keys screen in your dashboard, beside the key itself. It is the same id in every call you make.

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/sites/export \
  -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

The same sites listSites would return for the same query, as a streamed text/csv attachment — V1 parity (deploy.views.SiteExport, "Choose sites → Export to CSV"), recorded as unported in docs/35 §0.3c until W29-U. ⛔⛔ Server-side over the WHOLE matching set, and that is the point of it existing as an endpoint at all. listSites is cursor-paginated, so a CSV assembled in the browser would contain one page and would look exactly like a complete file — no error, no truncation marker, and nothing a customer could use to tell the difference. There is deliberately no limit: a bound here would silently exclude rows and nothing downstream would ever pick up the remainder. ⛔ It shares the list's filter chain rather than reproducing it, so "export" means "export what I am looking at" by construction. Every filter below behaves exactly as it does on listSites, including narrowing to nothing — rather than 403-ing — for an org_id outside the caller's scope. ⛔⛔ It requires Authorization, so it cannot be fetched with a plain <a href>. A browser anchor navigation sends no bearer token and the engine has no cookie authentication to fall back on, so an anchor answers 401 and the customer sees nothing happen. Download it with an authenticated fetch and hand the result to the browser as a blob. This is not hypothetical: the estate shipped three staff download buttons built as anchors and every one of them was dead (docs/72 D14200). The header row is English and is not localized: the consumer is a spreadsheet or a script, and a header that changed with the viewer's locale would make one customer's file unreadable by another's tooling. Column order is part of the contract — new columns are appended, never inserted.

Parameters

NameTypeRequiredWhat it is
org_id (query)UuidNoRestrict to one organization in the caller's scope.
status (query)SiteStatusNoFilter by site lifecycle status.
product_line (query)stringNoFilter by product line code.
group (query)stringNoRestrict to the sites in one site group.
server (query)stringNoRestrict to the sites on one server — a key from listSiteServers (and from each row's server.key): own:<uuid>, panel:<uuid>, fleet:<region>-<n>, or one of edge,…
search (query)stringNoCase-insensitive substring match on the primary domain or the name, applied in the database across the whole collection in scope.

Errors this endpoint can return

401 · 403