extras
GET /v1/extra-purchases/{purchaseId}
Get an extra purchase.
Authentication
Send an API key as a bearer token. The key must carry the billing.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/extra-purchases/{purchaseId} \
-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
Returns one extra purchase in scope with its status and outcome. Requires billing.view.
Parameters
| Name | Type | Required | What it is |
|---|---|---|---|
purchaseId (path) | Uuid | Yes | The extra purchase's id. |
Response
| Name | Type | Required | What it is |
|---|---|---|---|
id | Uuid | Yes | UUIDv7 identifier — sortable by creation time (docs/02 §8). |
org_id | Uuid | Yes | UUIDv7 identifier — sortable by creation time (docs/02 §8). |
extra_id | Uuid | Yes | UUIDv7 identifier — sortable by creation time (docs/02 §8). |
site_id | object | No | — |
domain_id | object | No | — |
order_id | object | No | The order this purchase was charged on — or, while awaiting_payment (Q225), is waiting to be paid on: settle it with payOrder. null for a staff comp or a purchase paid from… |
status | ExtraPurchaseStatus | Yes | An extra purchase's lifecycle state. awaiting_payment (Q225): placed by a one-click buy with nothing on file to charge, waiting for the customer to pay its order on-session —… |
category | string | Yes | — |
fulfilment_type | ExtraFulfilmentType | Yes | How an extra is delivered. |
interval | ExtraInterval | Yes | One-off charge or a recurring subscription. annual is a PURCHASE term only — an SEO tool bought twelve months at a time at V1's yearly saving (D19, 2026-09-25). No catalogue row… |
price | MoneyAmount | Yes | A money value — integer minor units + an ISO 4217 code (CLAUDE.md §2.8). |
recurrence | string<none, active, ended> | Yes | Whether 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_on | object | No | The 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. |
renews_as | null | object | No | Q321 — the smaller tier of the same SEO tool chosen for the next renewal (scheduleExtraTierSwitch), or null when the purchase renews as itself. |
arrears | null | ExtraPurchaseArrears | No | s1014 R40 GAP-5/6/7 (docs/747 §2b, V1 parity). null, or this add-on's unpaid renewal: grace — it keeps working until freezes_on (3 days after the renewal fell due); frozen… |
sla_due_at | object | No | — |
completed_at | object | No | — |
failure_reason | string | No | — |
created_at | string | Yes | — |
updated_at | string | Yes | — |
Errors this endpoint can return
401 · 403 · 404 · 429