curl --request POST \
--url https://api.isnap.ai/v1/pre-orders \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"preferred_area_codes": [
"415",
"628"
],
"inbound_only": false,
"billing_tier": "rental_iphone",
"billing_anchor_at": "2026-09-11T09:15:00Z",
"metadata": {
"crm_account_id": "acc_123"
}
}
'import requests
url = "https://api.isnap.ai/v1/pre-orders"
payload = {
"preferred_area_codes": ["415", "628"],
"inbound_only": False,
"billing_tier": "rental_iphone",
"billing_anchor_at": "2026-09-11T09:15:00Z",
"metadata": { "crm_account_id": "acc_123" }
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
preferred_area_codes: ['415', '628'],
inbound_only: false,
billing_tier: 'rental_iphone',
billing_anchor_at: '2026-09-11T09:15:00Z',
metadata: {crm_account_id: 'acc_123'}
})
};
fetch('https://api.isnap.ai/v1/pre-orders', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.isnap.ai/v1/pre-orders",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'preferred_area_codes' => [
'415',
'628'
],
'inbound_only' => false,
'billing_tier' => 'rental_iphone',
'billing_anchor_at' => '2026-09-11T09:15:00Z',
'metadata' => [
'crm_account_id' => 'acc_123'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.isnap.ai/v1/pre-orders"
payload := strings.NewReader("{\n \"preferred_area_codes\": [\n \"415\",\n \"628\"\n ],\n \"inbound_only\": false,\n \"billing_tier\": \"rental_iphone\",\n \"billing_anchor_at\": \"2026-09-11T09:15:00Z\",\n \"metadata\": {\n \"crm_account_id\": \"acc_123\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.isnap.ai/v1/pre-orders")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"preferred_area_codes\": [\n \"415\",\n \"628\"\n ],\n \"inbound_only\": false,\n \"billing_tier\": \"rental_iphone\",\n \"billing_anchor_at\": \"2026-09-11T09:15:00Z\",\n \"metadata\": {\n \"crm_account_id\": \"acc_123\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.isnap.ai/v1/pre-orders")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"preferred_area_codes\": [\n \"415\",\n \"628\"\n ],\n \"inbound_only\": false,\n \"billing_tier\": \"rental_iphone\",\n \"billing_anchor_at\": \"2026-09-11T09:15:00Z\",\n \"metadata\": {\n \"crm_account_id\": \"acc_123\"\n }\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"preferred_area_codes": [
"<string>"
],
"inbound_only": true,
"billing_anchor_at": "<string>",
"status": "draft",
"stripe_client_secret": "<string>",
"estimated_fulfillment": "<string>",
"created_at": "<string>",
"updated_at": "<string>",
"metadata": {
"crm_account_id": "acc_123"
},
"device_status": "awaiting_hardware"
},
"trace_id": "<string>",
"request_id": "<string>"
}{
"success": false,
"data": "<unknown>",
"error": {
"status": 123,
"code": "<string>",
"message": "<string>",
"retry_after": 123,
"retry_at": "<string>",
"issues": [
{
"path": [
"<string>"
],
"message": "<string>",
"code": "<string>",
"min": 123,
"max": 123
}
]
},
"trace_id": "<string>",
"request_id": "<string>"
}{
"success": false,
"data": "<unknown>",
"error": {
"status": 123,
"code": "<string>",
"message": "<string>",
"retry_after": 123,
"retry_at": "<string>",
"issues": [
{
"path": [
"<string>"
],
"message": "<string>",
"code": "<string>",
"min": 123,
"max": 123
}
]
},
"trace_id": "<string>",
"request_id": "<string>"
}{
"success": false,
"data": "<unknown>",
"error": {
"status": 123,
"code": "<string>",
"message": "<string>",
"retry_after": 123,
"retry_at": "<string>",
"issues": [
{
"path": [
"<string>"
],
"message": "<string>",
"code": "<string>",
"min": 123,
"max": 123
}
]
},
"trace_id": "<string>",
"request_id": "<string>"
}{
"success": false,
"data": "<unknown>",
"error": {
"status": 123,
"code": "<string>",
"message": "<string>",
"retry_after": 123,
"retry_at": "<string>",
"issues": [
{
"path": [
"<string>"
],
"message": "<string>",
"code": "<string>",
"min": 123,
"max": 123
}
]
},
"trace_id": "<string>",
"request_id": "<string>"
}Create a pre-order
Creates a draft pre-order for one rented iMessage line, which has no effect until you confirm it.
curl --request POST \
--url https://api.isnap.ai/v1/pre-orders \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"preferred_area_codes": [
"415",
"628"
],
"inbound_only": false,
"billing_tier": "rental_iphone",
"billing_anchor_at": "2026-09-11T09:15:00Z",
"metadata": {
"crm_account_id": "acc_123"
}
}
'import requests
url = "https://api.isnap.ai/v1/pre-orders"
payload = {
"preferred_area_codes": ["415", "628"],
"inbound_only": False,
"billing_tier": "rental_iphone",
"billing_anchor_at": "2026-09-11T09:15:00Z",
"metadata": { "crm_account_id": "acc_123" }
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
preferred_area_codes: ['415', '628'],
inbound_only: false,
billing_tier: 'rental_iphone',
billing_anchor_at: '2026-09-11T09:15:00Z',
metadata: {crm_account_id: 'acc_123'}
})
};
fetch('https://api.isnap.ai/v1/pre-orders', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.isnap.ai/v1/pre-orders",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'preferred_area_codes' => [
'415',
'628'
],
'inbound_only' => false,
'billing_tier' => 'rental_iphone',
'billing_anchor_at' => '2026-09-11T09:15:00Z',
'metadata' => [
'crm_account_id' => 'acc_123'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.isnap.ai/v1/pre-orders"
payload := strings.NewReader("{\n \"preferred_area_codes\": [\n \"415\",\n \"628\"\n ],\n \"inbound_only\": false,\n \"billing_tier\": \"rental_iphone\",\n \"billing_anchor_at\": \"2026-09-11T09:15:00Z\",\n \"metadata\": {\n \"crm_account_id\": \"acc_123\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.isnap.ai/v1/pre-orders")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"preferred_area_codes\": [\n \"415\",\n \"628\"\n ],\n \"inbound_only\": false,\n \"billing_tier\": \"rental_iphone\",\n \"billing_anchor_at\": \"2026-09-11T09:15:00Z\",\n \"metadata\": {\n \"crm_account_id\": \"acc_123\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.isnap.ai/v1/pre-orders")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"preferred_area_codes\": [\n \"415\",\n \"628\"\n ],\n \"inbound_only\": false,\n \"billing_tier\": \"rental_iphone\",\n \"billing_anchor_at\": \"2026-09-11T09:15:00Z\",\n \"metadata\": {\n \"crm_account_id\": \"acc_123\"\n }\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"preferred_area_codes": [
"<string>"
],
"inbound_only": true,
"billing_anchor_at": "<string>",
"status": "draft",
"stripe_client_secret": "<string>",
"estimated_fulfillment": "<string>",
"created_at": "<string>",
"updated_at": "<string>",
"metadata": {
"crm_account_id": "acc_123"
},
"device_status": "awaiting_hardware"
},
"trace_id": "<string>",
"request_id": "<string>"
}{
"success": false,
"data": "<unknown>",
"error": {
"status": 123,
"code": "<string>",
"message": "<string>",
"retry_after": 123,
"retry_at": "<string>",
"issues": [
{
"path": [
"<string>"
],
"message": "<string>",
"code": "<string>",
"min": 123,
"max": 123
}
]
},
"trace_id": "<string>",
"request_id": "<string>"
}{
"success": false,
"data": "<unknown>",
"error": {
"status": 123,
"code": "<string>",
"message": "<string>",
"retry_after": 123,
"retry_at": "<string>",
"issues": [
{
"path": [
"<string>"
],
"message": "<string>",
"code": "<string>",
"min": 123,
"max": 123
}
]
},
"trace_id": "<string>",
"request_id": "<string>"
}{
"success": false,
"data": "<unknown>",
"error": {
"status": 123,
"code": "<string>",
"message": "<string>",
"retry_after": 123,
"retry_at": "<string>",
"issues": [
{
"path": [
"<string>"
],
"message": "<string>",
"code": "<string>",
"min": 123,
"max": 123
}
]
},
"trace_id": "<string>",
"request_id": "<string>"
}{
"success": false,
"data": "<unknown>",
"error": {
"status": 123,
"code": "<string>",
"message": "<string>",
"retry_after": 123,
"retry_at": "<string>",
"issues": [
{
"path": [
"<string>"
],
"message": "<string>",
"code": "<string>",
"min": 123,
"max": 123
}
]
},
"trace_id": "<string>",
"request_id": "<string>"
}- Credential: an API key.
- Line-scoped keys: the list of lines of a line-scoped key is not applied.
Idempotency-Key: not honored. A repeated call creates another draft. See Operations that honor the key.- Events: none. See Events.
- Effect: a draft creates no line and takes no payment.
POST /v1/pre-orders/{id}/confirmcommits it: see How a pre-order works. - Caching: the response carries
Cache-Control: no-store, whatever its status.
Errors
| Status | error.code | When |
|---|---|---|
| 400 | validation_failed | An unknown field, quantity included, more than 5 area codes, a value of the wrong type, or a metadata over 20 keys or 8,192 bytes. |
| 400 | android_rental_not_purchasable | billing_tier is rental_android. |
| 400 | tier_not_pre_orderable | billing_tier is byod_imessage, byod_android, shared_pool or shared_imessage. |
| 400 | billing_anchor_too_far | billing_anchor_at is more than 31 days after the call. |
Authorizations
An API key created in the iSnap dashboard, or a trial key, sent as Authorization: Bearer <key>. An API key starts with isnap_live_ or isnap_test_; both act on the same account, lines and billing. A trial key acts on its trial only.
Body
Area codes you accept for the number of the line, in order of preference: 0 to 5 strings of 1 to 10 characters. Default: an empty list, which accepts any area code.
51 - 10["415", "628"]
true orders an inbound-only line, false a two-way line. Default: false.
Optional. Only rental_iphone is accepted: rental_android returns 400 android_rental_not_purchasable, and byod_imessage, byod_android, shared_pool and shared_imessage return 400 tier_not_pre_orderable. The value is neither stored nor returned.
rental_iphone, rental_android, byod_imessage, byod_android, shared_pool, shared_imessage "rental_iphone"
The billing anchor of the line: an ISO 8601 timestamp in UTC, with a Z suffix. A line billed on the monthly wholesale invoice is charged one full month at each monthly occurrence of this timestamp: the same day of the month, moved to the last day of a shorter month, at the same time of day. At the first occurrence after its activation, the line is also credited for the days that the month charged at activation had already paid for past that occurrence. Omit it to bill the line at each monthly occurrence of its activation. A past timestamp is accepted. A timestamp more than 31 days after the request returns 400 billing_anchor_too_far.
"2026-09-11T09:15:00Z"
Your own key-value data. iSnap stores it as sent and does not interpret it. Events about this resource carry it in data.metadata. At most 20 keys and 8,192 bytes once serialized as JSON.
Show child attributes
Show child attributes
{ "crm_account_id": "acc_123" }
Response
The pre-order, in status draft.
Always true on a success response.
true A pre-order: an order for one rented iMessage line.
Show child attributes
Show child attributes
Trace id of the request that produced this response: 32 lowercase hexadecimal characters. Quote it when you report a problem to iSnap.
Id of the request that produced this response: req_ followed by 25 letters or digits.