Skip to main content
A pre-order asks iSnap to prepare one rented iMessage line (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 has area_code, region, country_code, purchase_zip, alt_zips and shared_with. The list is ordered by country_code, then by area_code.
  • countries: each entry has country_code, name and calling_code.
The query parameter 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_fulfillment is 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 the inbound_only that you ordered and your billing_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 no preferred_area_codes takes 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 has status: 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} until status is provisioning: that read checks the payment, and starts the build when the payment has succeeded. GET /v1/pre-orders does 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 sends pre_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: provisioning and stripe_client_secret: null to a direct account: its first month was already paid, and the build has started.
A direct account can repeat the confirmation while the pre-order is 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.
stripe_client_secret is returned only by the confirm response of a pre-order in awaiting_payment: every other response returns null. confirm does not honor Idempotency-Key.Once its build has started, a pre-order cannot be canceled through the API. Confirm only when the order is final.
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 same stripe_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.
Two refusals concern the payment of the first month, on the confirmation and on the cancellation. 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 an isnap_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
The 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: the stripe_client_secret of the confirmation can no longer be used.
  • When the first month is already paid, the call returns 409 pre_order_already_paid and the build goes on.
  • A pre-order in provisioning, fulfilled or cancelled returns 400 pre_order_already_confirmed.
  • 503 payment_provider_unavailable and 409 payment_setup_failed mean what they mean for the confirmation: see Confirm and payment.
No operation ends a pre-order whose build has started. The message of the 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

Set metadata 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 PATCH merges: a key that you send replaces the stored value, a key sent as null is deleted, and the other keys stay. {"metadata": {}} changes nothing.
  • The metadata of 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 PATCH works in every status.
  • The events sent after the PATCH carry the new metadata in data.metadata.
  • The metadata of 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 status filter. Send the same status on 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_fulfillment that passes;
  • an order that iSnap withdraws behind a pre-order whose build has started.
The full list is in What events do not announce. To know the state of a pre-order, read it with 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 its metadata. pre_order.fulfilled carries the full phone number of the new line. Do not copy it into logs, tickets or other tools.