When to use this
Use the anonymous variant when:
- You manage the end-user relationship entirely in your own system
- You do not want kurnl to store subscriber PII
- You use your own invoicing and billing — kurnl should not issue invoices on your behalf
With the anonymous variant, subscribers have no kurnl self-service portal access and kurnl cannot issue invoices on your behalf.
If you want kurnl to manage subscriber records and billing, use CKO-03 direct delivery instead.
How it works
The flow is identical to direct delivery, except:
- You provide your own
external_subscription_id instead of a subscriber object
- kurnl provisions the port but creates no subscriber record
- No
subscriber_id is returned
Step-by-step
Identical to direct delivery — see CKO-03 Direct: Step 1.
2. Collect payment in your own system
Handle the full checkout and payment in your own system. kurnl receives no customer data.
3. Call kurnl after successful payment
curl -X POST https://api.kurnl.ca/api/v1/partner/external-checkout/anonymous-complete \
-H "Content-Type: application/json" \
-H "X-Webhook-Secret: YOUR_WEBHOOK_SECRET" \
-d '{
"service_provider_document_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"plan_version_id": "f7e8d9c0-b1a2-3456-cdef-012345678901",
"delivery_mode": "direct",
"location_hash": "ab12cd34ef",
"external_subscription_id": "your-internal-id-123"
}'
Successful response — 200 OK:
{
"job_id": "3d6e8f12-...",
"subscription_id": "8c4a1b9e-...",
"message": "Provisioning started"
}
No subscriber_id is returned — no subscriber record is created. Store the subscription_id to correlate with webhook events.
4. Handle webhook events
| Event | When | Key fields |
|---|
provisioning.completed | ~30 seconds — port is live | job_id, subscription_id |
provisioning.failed | If SSH provisioning fails | job_id, subscription_id, error |
At provisioning.completed, the subscriber’s internet is live.
See Webhooks for signature verification and retry behaviour.
Field reference
| Field | Type | Required | Notes |
|---|
service_provider_document_id | UUID | Yes | Your provider UUID |
plan_version_id | UUID | Yes | From the marketplace redirect URL |
delivery_mode | "direct" | "home_drop" | No | Defaults to "direct" |
location_hash | string (10 hex chars) | Yes (direct) | From the marketplace redirect URL |
unit_id | UUID | Yes (home_drop) | From the marketplace redirect URL |
external_subscription_id | string | Yes | Your own per-subscription identifier — acts as idempotency key |
mac_address | string | No | Enables port security (static MAC binding) on the switch |
Error handling
| Status | Error | What to do |
|---|
| 401 | X-Webhook-Secret header required | Add the header |
| 401 | Invalid webhook secret | Check your secret in the dashboard |
| 404 | Location not found for location_hash | Hash expired or invalid |
| 429 | Rate limit exceeded | 120 requests/minute per IP |
On 5xx errors or network timeout: Safe to retry — the request is idempotent. The same external_subscription_id returns the existing job_id rather than creating a duplicate.