Purchase Blooio numbers
/channels/blooio/purchasesPurchase one or more Blooio lines. Purchases are asynchronous and billable: the call charges the organization's credit balance, then its default payment method, and returns a purchase_id; the lines are provisioned when Stripe confirms the invoice, at which point a number.purchase.completed webhook fires (or number.purchase.failed). A card requiring 3DS/SCA returns status: action_required with an action_url, and also emits number.purchase.action_required.
Idempotency is required — send a unique Idempotency-Key header; replaying the same key returns the same purchase rather than charging twice.
Rules enforced server-side (identically to the dashboard): without a saved payment method, the organization's credit must cover the purchase in full (else 402 no_payment_method, and nothing is charged); shared plans are limited to one line per organization (409 shared_number_limit); and a single order may not exceed the per-order line cap (400 line_limit_exceeded, default 10 — apply for an increase in the dashboard Limits tab). Requested area codes that are out of stock incur a custom area-code fee and open a provisioning ticket; in-stock codes are assigned immediately with no custom fee.
Custom requests. For anything the pool can't fill automatically (installing your own eSIM, porting in a number, a number from another country), send custom_requests: one entry per line, matched to lines by position like area_codes. Each line with a custom request is charged the one-time custom fee, is never assigned automatically, and opens a provisioning ticket carrying your notes. The line stays pending (phone_number: null, with a ticket_id in the purchase status) until Blooio staff provision it. Read the ticket with GET /v4/tickets/{ticketId}.
Requires the number purchase API feature to be enabled, and the numbers:manage scope for OAuth apps.
Headers
AuthorizationRequiredstringYour API key, sent as a bearer token: Authorization: Bearer <api_key>. Editing this stays in sync with the API key box on the right.
Idempotency-KeyRequiredstringUnique key that makes the billable purchase safe to retry.
Body parameters
JSONplanRequiredstringPlan id to purchase (determines shared / dedicated / inbound). Use the specific id, not the tier name — e.g. dedicated_com or dedicated_ent, not dedicated (which returns invalid_plan).
"shared_nc""shared_com""dedicated_com""dedicated_ent""inbound_basic"quantityoptionalintegerNumber of new lines (dedicated/inbound). Shared is always 1.
area_codesoptionalstring[]Preferred 3-digit US area codes (dedicated/inbound). Out-of-stock codes incur a custom fee and open a ticket.
zip_codesoptionalstring[]Preferred ZIP codes (dedicated/inbound), used when an area code is not specified.
custom_requestsoptionalobject | null[]Per-line custom provisioning requests (dedicated/inbound only), matched to lines by position. An object marks that line for manual provisioning by Blooio staff; null (or no entry) leaves the line on normal fulfillment. May not have more entries than quantity. Each custom line is charged the one-time custom fee and opens a provisioning ticket. Notes are stored as sent and shown on the ticket to your organization and Blooio staff.
custom_requestsoptionalobject | null[]Per-line custom provisioning requests (dedicated/inbound only), matched to lines by position. An object marks that line for manual provisioning by Blooio staff; null (or no entry) leaves the line on normal fulfillment. May not have more entries than quantity. Each custom line is charged the one-time custom fee and opens a provisioning ticket. Notes are stored as sent and shown on the ticket to your organization and Blooio staff.
Array of object | null
object
notesoptionalstring | nullFree-text instructions for Blooio staff, e.g. eSIM details, a number to port in, or the country you need. Optional.
auto_bindoptionalstringapi_key_id of an API key in your organization that should own every line in this purchase. Each line is assigned to the key as soon as it gets its number, including lines Blooio staff provision later (custom requests, ZIP codes, out-of-stock area codes), so sends authenticated with that key can use them without a separate assignment call. A key deprecated before its line is provisioned is not assigned. Unknown keys return 404 auto_bind_api_key_not_found. Plans without number pools (shared_nc, shared_com, dedicated_com) let a key own one line, so on those plans auto_bind requires quantity: 1 and a key holding no other line on such a plan (else 409 auto_bind_exceeds_plan).
Returns
dataoptionalobject
dataoptionalobjectpurchase_idoptionalstringstatusoptionalstring"provisioning""action_required"action_urloptionalstring | nullPresent when status is action_required: complete card authentication here.
Response codes
Sends a live request with your values and shows the real response below. Your key is stored only in this browser.
curl -X POST https://api.blooio.com/v4/channels/blooio/purchases \{ "data": { "purchase_id": "idem_abc123", "status": "provisioning" }}