billing_tier: rental_iphone) for your account, preferably with a number in one of up to 5 area codes that you choose. It has two steps: a draft, which has no effect, then a confirmation, which commits the order. A direct account then pays the first month in the iSnap dashboard before iSnap builds the line. Read this page when you order a line instead of taking one from the marketplace.
One pre-order is one line. To order several lines, create several pre-orders.
How a pre-order works
1
Choose area codes
Call
GET /v1/area-codes. It needs no credential and returns the whole list in one response:area_codes: each entry hasarea_code,region,country_code,purchase_zip,alt_zipsandshared_with. The list is ordered bycountry_code, then byarea_code.countries: each entry hascountry_code,nameandcalling_code.
country takes 2 letters, case-insensitive, and keeps the area codes of that country. A country with no area code returns an empty area_codes. countries is never filtered.The list contains the area codes that you can request on a pre-order. It does not say which lines are in stock: the marketplace does. When shared_with is not empty, it names the other area codes of the list that cover the same geography, and the number that you obtain can carry any of them. purchase_zip, which can be null, and alt_zips are ZIP codes of that geography.2
Create a draft
Call
POST /v1/pre-orders. Every field of the body is optional:Any other field,
quantity included, returns 400 validation_failed.The response is 201 with the pre-order, status: draft. A draft creates no line, takes no payment and starts nothing at iSnap. A draft never expires, and the API sets no maximum number of drafts.3
Confirm
Call
POST /v1/pre-orders/{id}/confirm. Only a draft can be confirmed, and a direct account can repeat the confirmation while the first month is due. The build of the line starts with the confirmation for a wholesale partner, and once the first month is paid for a direct account: see Confirm and payment. When the build starts:- The pre-order gets
status: provisioning. estimated_fulfillmentis set to the time the build starts plus 72 hours.- iSnap creates a line on your account with
status: provisioning: a rented iMessage line (billing_tier: rental_iphone), with theinbound_onlythat you ordered and yourbilling_anchor_at. When a number is in stock in one of your area codes, in their order of preference, the line receives it when the build starts. A pre-order with nopreferred_area_codestakes any number in stock.
4
Receive the line
When iSnap hands the line over, the pre-order becomes
fulfilled and iSnap sends pre_order.fulfilled once, with pre_order_id, line_id, phone_number (the full number of the line, which can be null), billing_tier and fulfilled_at. The pre-order itself carries no line id: you learn the line from this event, or by reading your lines with GET /v1/lines/my. A line-scoped key does not see the new line in GET /v1/lines/my, since the line is not in its list: read the line id from the event, or list with a key that has no list of lines.A direct account also receives an email that says the line is ready. A wholesale partner receives no email.Confirm and payment
Wholesale partner. The build starts with the confirmation: the response hasstatus: provisioning, and stripe_client_secret is null. Nothing is paid at confirmation. The line is counted on your monthly invoice from the day it goes live.
Direct account. The build starts once the first month is paid. The confirmation starts the monthly billing of the line and returns the pre-order with status: awaiting_payment and stripe_client_secret, the secret of the first monthly payment: do not log it. No line exists yet, and estimated_fulfillment is null.
- Pay the first month in the iSnap dashboard, by card, within 23 hours of the confirmation. No operation that an API key can call pays it. See Accounts.
- Once iSnap has recorded the payment, the build starts. Read the pre-order with
GET /v1/pre-orders/{id}untilstatusisprovisioning: that read checks the payment, and starts the build when the payment has succeeded.GET /v1/pre-ordersdoes not check it: see Listing. - When the first month is not paid within 23 hours of the confirmation, it can no longer be paid: the pre-order becomes
cancelled, no line is built, and iSnap sendspre_order.cancelled. The API does not bound the delay between the end of the 23 hours and that change. To order the line again, create a new draft. - The first month starts at the confirmation, not at the hand-over. The hand-over takes no payment.
- The confirmation can also return
status: provisioningandstripe_client_secret: nullto a direct account: its first month was already paid, and the build has started.
awaiting_payment: it returns the same stripe_client_secret and starts no second billing. Repeated after the payment succeeded, it returns the pre-order in provisioning, with stripe_client_secret: null. A wholesale partner cannot repeat a confirmation: 400 pre_order_not_draft.
When the response to a confirmation is lost, or the call returns a 500 or a 503, read the pre-order with GET /v1/pre-orders/{id} before you do anything else:
status: draft: the confirmation did not happen. Resend it.status: awaiting_payment: the confirmation happened, and the first month is due. Pay it in the dashboard. Resending the confirmation returns the samestripe_client_secret.status: provisioning: the build has started, and nothing is due.status: cancelled: the pre-order was canceled, or its first month was not paid within 23 hours. Create a new draft to order the line again.
503 payment_provider_unavailable: iSnap could not reach its payment provider, nothing changed, and the call can be resent. 409 payment_setup_failed: the payment provider refused the request for your account, nothing changed, and resending the call does not help. Write to support@isnap.ai with the trace_id and request_id of the response.
A confirmation acts the same way with every API key:
- Test keys. An
isnap_test_account key is not a separate test environment: it acts on the same account, lines and billing as anisnap_live_key. A confirmation sent with a test key is a real order, billed like any other. See Test keys. - Line-scoped keys. The list of lines of a line-scoped key is not applied to pre-orders: such a key can create and confirm a pre-order.
Create a draft and confirm it
Draft
id of a pre-order is a UUID, with no prefix.
Estimated date
estimated_fulfillment is null until the build starts: on a draft, on a pre-order in awaiting_payment, and on a pre-order canceled before its build started. The start of the build sets it once, to that time plus 72 hours, and nothing revises it afterward. The 72 hours are a setting of iSnap, the same for every pre-order. No field and no event tells you that the date has passed without a hand-over.
Statuses
A pre-order whose build has started never becomes
cancelled. If iSnap withdraws the line before the hand-over, the pre-order stays provisioning and no event is sent.
device_status tells how far the line is. It is always present and never null:
The schema also lists
received and setup_in_progress. The API does not return them. Ignore response fields, enum values and event types you do not know.
Canceling
POST /v1/pre-orders/{id}/cancel cancels a pre-order in draft or awaiting_payment: the pre-order gets status: cancelled, nothing was charged, and iSnap sends pre_order.cancelled. The event is sent after the cancel is recorded: if it cannot be sent, the cancel stands.
- For a pre-order in
awaiting_payment, the payment of the first month is canceled first: thestripe_client_secretof the confirmation can no longer be used. - When the first month is already paid, the call returns
409 pre_order_already_paidand the build goes on. - A pre-order in
provisioning,fulfilledorcancelledreturns400 pre_order_already_confirmed. 503 payment_provider_unavailableand409 payment_setup_failedmean what they mean for the confirmation: see Confirm and payment.
400 above points to POST /v1/lines/{id}/release, but release only gives back a line that you have reserved: it returns 404 for a line that is being prepared. POST /v1/lines/{id}/terminate refuses that line too. To withdraw such a pre-order, write to support@isnap.ai with the id of the pre-order.
Metadata
Setmetadata when you create the draft, and change it with PATCH /v1/pre-orders/{id}. The body of the PATCH is required and has one field, metadata. Send Content-Type: application/json with every body.
- The
PATCHmerges: a key that you send replaces the stored value, a key sent asnullis deleted, and the other keys stay.{"metadata": {}}changes nothing. - The
metadataof the request and the result each contain at most 20 keys and 8,192 bytes once serialized. A request that only deletes keys is never refused for the size of the result. - The
PATCHworks in every status. - The events sent after the
PATCHcarry the newmetadataindata.metadata. - The
metadataof a pre-order is not copied to the line that it produces.
Listing
GET /v1/pre-orders lists your pre-orders, newest first.
The response has
data.items, data.has_more and data.next_cursor. next_cursor is null on the last page.
The list does not check payments: a pre-order whose first month was just paid can be listed as awaiting_payment until iSnap records the payment. GET /v1/pre-orders/{id} checks it.
Two rules of the cursor, described with the other lists in Cursors:
- A cursor that cannot be read does not return an error: the list starts again from the first page, with
200. - The cursor does not carry the
statusfilter. Send the samestatuson every page of one walk, or pre-orders are skipped.
Events
A pre-order does not give you its line id before the hand-over: receive pre-order events on a webhook subscription without a line filter. When the line is handed over with its device already connected, iSnap also sends
line.connected for it.
The pre-order events announce the two changes above, and no other. No event announces:
- a draft that is created;
- a confirmation: its response is the only signal;
- a first month that is paid, and the start of the build: read the pre-order;
- a change of
metadata; - an
estimated_fulfillmentthat passes; - an order that iSnap withdraws behind a pre-order whose build has started.
GET /v1/pre-orders/{id}. Deduplicate on event_id: see Duplicates.
Errors
The refusals of each operation are on its reference page:GET /v1/area-codes, POST /v1/pre-orders, GET /v1/pre-orders, GET /v1/pre-orders/{id}, PATCH /v1/pre-orders/{id}, POST /v1/pre-orders/{id}/confirm and POST /v1/pre-orders/{id}/cancel. The errors that every operation shares are in Errors.
Personal data
A pre-order carries no data beyond what you put in itsmetadata. pre_order.fulfilled carries the full phone number of the new line. Do not copy it into logs, tickets or other tools.