When to use this

Bulk provisioning is designed for:
  • Migrations — moving a large subscriber base from another platform to kurnl
  • New building activations — activating an entire MDU building at once when all units are pre-wired
  • Batch imports — provisioning a list of new subscribers from a CSV or external system
For single subscribers, use CKO-04 provider-initiated or CKO-03 instead.

How it works

The POST is synchronous per item: kurnl creates the subscriber and subscription and queues the SSH job for every item inline, then returns 200 with a per-item result list. Only the switch SSH step runs in the background — expect a long-running request for big batches. You then poll the batch status endpoint to track the SSH jobs.

Submit a batch

Each item wraps the full subscriber object (same shape as provider-initiated provisioning) plus a plan_version_id, a location_hash or location_identifier, and optionally a billing block (see Billing per item).
Response — 200 OK (synchronous, per-item results):
status per item is "queued" or "error".

Poll for status

Response:
job_status is one of pending, running, completed, failed, error, unknown. There is no batch-level status field — aggregate the item states client-side (the batch is done when no item is pending or running). Unknown batch_id returns 404; another provider’s batch returns 403.

Handling partial failures

Individual item failures don’t stop the rest of the batch: failed items come back with "status": "error" and an "error" message in the POST response. Fix the cause (e.g. correct the location hash) and resubmit those items. Resubmitting is safe: provisioning is idempotent per item — the same subscriber email + plan version + location returns the existing subscription instead of creating a duplicate.

Billing per item

Every item takes the same optional billing block as a single provider-initiated order. Without it kurnl provisions and you bill. With owner: "kurnl" and the customer’s id from your Stripe account, kurnl adopts that customer and bills the subscription — a prorated first invoice at activation, then monthly on billing_day:
A batch may mix partner-billed and kurnl-billed items. The billing pre-flight runs per item, before that item writes anything: an item that fails it comes back with "status": "error" and the reason in error, prefixed with the code (billing_not_available, stripe_customer_not_found, stripe_customer_has_no_payment_method, stripe_customer_in_use, stripe_unavailable), and the rest of the batch continues. Each item’s result carries billing_owner so you can confirm what kurnl recorded.

Limits

If you need to provision more than 100 subscribers, split them into multiple batches (mind the 10/min rate limit on the POST).

Migration checklist

Before running a bulk migration:
1

Map location hashes

Every subscriber needs a valid location_hash corresponding to a kurnl switch port. Work with your kurnl account manager to get a mapping from your building/unit records to kurnl location hashes.
2

Validate plan versions

Confirm your plan_version_id values are active. Expired plan versions will cause the entire subscriber entry to fail.
3

Test with a small batch

Run a batch of 3–5 subscribers first and verify they provision correctly before running the full migration.
4

Run in off-peak hours

Large batches generate significant switch SSH traffic. Schedule migrations during low-traffic periods.
5

Handle failed entries

After the batch completes, process failed entries individually. Log the errors, fix the root cause, and resubmit.