See CKO-03 Anonymous for the full guide.

Endpoint

Authentication

X-Webhook-Secret header. This is the flow the kurnl Marketplace uses. With session_id set, the session supplies the plan, building, location/unit and MAC address — only external_subscription_id is additionally required (and contact_email when the order needs a visit, see below). Any of the explicit fields below included alongside a session_id are ignored in favor of the session.
A discount code the session itself carries applies here too, on the same terms as /external-checkout/complete: resolved as of the session’s creation day, and if it was archived meanwhile it lapses without failing the order. That silent lapse covers only the session’s own code. A discount_code you send in the body is checked as of the hand-over against the session’s building: a kurnl operator code from the session’s operator_offers or one of your own discount codes is honoured; anything else is a 400 (Invalid or expired discount code) and nothing is created. The session’s own code sent back counts as no code. Check it before you charge, and on a 400 retry without the code (the plan’s campaign price if a campaign is live, otherwise the list price). A bulk plan takes no code (422 bulk_discount). If the code cannot be checked right now, the call answers 503 (Could not check the discount code; try again.): retry.
The building decides the path, as on /external-checkout/complete, not the delivery_mode of the session or of your payload:
  • a first-line building is provisioned at once (ACTIVE) — a shared first-line suite is held as an install job until the operator confirms the connection;
  • a second- or third-line suite whose router is already online (a suite of one) is provisioned at once too;
  • every other suite — router not online, a shared suite, or any suite in an unclassified building — gets PENDING_INSTALL and an operator install job.
delivery_mode in the response reports the path taken: direct = provisioned, home_drop = install job. A direct order (a port, no suite) on a building that is not first line is refused with 422: outside first line kurnl needs the suite.

Request body — explicit fields (no session)

external_subscription_id is your own per-subscription identifier and acts as the idempotency key. contact_email (either path) is an e-mail for the household behind the line. It is stored on the subscription only — no customer record is created. It is required when the order needs a technician visit or a shipped router: a second- or third-line building, unless the suite’s router is already online, and an unclassified building, even when the suite’s router is online. Without it such an order is refused with 422 contact_email_required and nothing is created. On a first-line building, and for a second- or third-line suite whose router is already online, it is optional. On a third-line building it is the address the technician booking link is e-mailed to; the customer picks and manages the visit window from that link. Later it also serves the provider’s own outage notices. The provider can add or change it in the portal.

Response — 200 OK

No subscriber_id is returned — no subscriber record is created. An order for a shared suite takes the install path. It is re-anchored to the suite’s first free connection and stays PENDING_INSTALL as usual; unit_confirmation_pending: true says the operator still has to confirm which connection is the customer’s. If every connection of the suite is taken the call is refused with 409 no_free_connection. Replays (same external_subscription_id or already-completed session_id) report the subscription’s real current status — e.g. PENDING_INSTALL for a home-drop order still awaiting install.

Error codes