hosting

POST /v1/sites/{siteId}/migrations/managed-request

Buy the managed migration and let staff do it.

All hosting endpoints

Authentication

Send an API key as a bearer token. The key must carry the billing.payment.manage 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 POST https://api.zinndigital.com/v1/sites/{siteId}/migrations/managed-request \
  -H "Authorization: Bearer zdk_live_…" \
  -H "Content-Type: application/json" \
  -d '{  }'

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

Purchases the `managed_migration` extra — the paid, staff-run service the catalogue sells with a 72-hour SLA — for this site. The self-service migration above and this both exist; neither is a placeholder for the other, and this is the path for a source we cannot automate (Plesk, an unusual panel, a site nobody has the credentials for any more). It creates an **`ExtraPurchase`**, not a migration job: the charge, the tax, the invoice line and the SLA clock all come from the extras machinery, and the fulfilment workflow raises it to the staff queue. Returns the purchase, so the client can show its status and SLA. A declined card is 422 and nothing is booked; an environment whose catalogue has never been seeded answers 503 rather than 404, because the service exists and is advertised. An organization with **no** chargeable payment method gets 422 `PAYMENT_METHOD_REQUIRED` rather than the decline code — nothing reached a gateway, so nothing was refused (`docs/491` §7). ⛔ Send **no credentials** here — the body has nowhere to put them, and staff collect them out of band from a human they can verify. Requires `billing.payment.manage`, not `hosting.import.manage`: this spends money, and a developer who may migrate a site may not charge the account.

Parameters

NameTypeRequiredWhat it is
siteId (path)UuidYesSite ID (UUIDv7).
Idempotency-Key (header)stringNoClient-generated key that makes an unsafe request replay-safe: the server stores the first response and returns it verbatim for repeats.

Request body

NameTypeRequiredWhat it is
source_hoststringNoWhere the site is hosted today, so the fulfilment queue is actionable without a round trip. A hostname, never a login. Optional.
notestringNoAnything else staff should know before they start.
currencystringNoThe currency the customer was quoted in. Validated and refused if no gateway can charge it — this is a charge, and silently substituting the base currency would bill a different…

Response

NameTypeRequiredWhat it is
idUuidYesUUIDv7 identifier — sortable by creation time (docs/02 §8).
org_idUuidYesUUIDv7 identifier — sortable by creation time (docs/02 §8).
extra_idUuidYesUUIDv7 identifier — sortable by creation time (docs/02 §8).
site_idobjectNo
domain_idobjectNo
statusExtraPurchaseStatusYesAn extra purchase's lifecycle state.
categorystringYes
fulfilment_typeExtraFulfilmentTypeYesHow an extra is delivered.
intervalExtraIntervalYesOne-off charge or a recurring subscription.
priceMoneyAmountYesA money value — integer minor units + an ISO 4217 code (CLAUDE.md §2.8).
recurrencestring<none, active, ended>YesWhether the recurrence behind this purchase is still live. `none` = it never recurred (a one-off); `active` = a scheduled charge exists; `ended` = it recurred and no longer does…
next_renewal_onobjectNoThe next charge date, or `null`. Also `null` for a live charge that has no date scheduled yet, so read `recurrence` — not this field — to decide whether a purchase renews at all.
sla_due_atobjectNo
completed_atobjectNo
failure_reasonstringNo
created_atstringYes
updated_atstringYes

Errors this endpoint can return

401 · 403 · 404 · 422 · 429 · 503