curl --request POST \
--url https://api.isnap.ai/v1/trial/init \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"max_outbound_without_inbound": 10,
"welcome_message": "You are connected to Acme. Reply here at any time.",
"footer": "Sent free via Acme",
"metadata": {
"crm_account_id": "acc_123"
}
}
'import requests
url = "https://api.isnap.ai/v1/trial/init"
payload = {
"max_outbound_without_inbound": 10,
"welcome_message": "You are connected to Acme. Reply here at any time.",
"footer": "Sent free via Acme",
"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({
max_outbound_without_inbound: 10,
welcome_message: 'You are connected to Acme. Reply here at any time.',
footer: 'Sent free via Acme',
metadata: {crm_account_id: 'acc_123'}
})
};
fetch('https://api.isnap.ai/v1/trial/init', 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/trial/init",
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([
'max_outbound_without_inbound' => 10,
'welcome_message' => 'You are connected to Acme. Reply here at any time.',
'footer' => 'Sent free via Acme',
'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/trial/init"
payload := strings.NewReader("{\n \"max_outbound_without_inbound\": 10,\n \"welcome_message\": \"You are connected to Acme. Reply here at any time.\",\n \"footer\": \"Sent free via Acme\",\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/trial/init")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"max_outbound_without_inbound\": 10,\n \"welcome_message\": \"You are connected to Acme. Reply here at any time.\",\n \"footer\": \"Sent free via Acme\",\n \"metadata\": {\n \"crm_account_id\": \"acc_123\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.isnap.ai/v1/trial/init")
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 \"max_outbound_without_inbound\": 10,\n \"welcome_message\": \"You are connected to Acme. Reply here at any time.\",\n \"footer\": \"Sent free via Acme\",\n \"metadata\": {\n \"crm_account_id\": \"acc_123\"\n }\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"trial_id": "trl_4Lp8Rn2xY7wQ9mK3vB5nH8dF2",
"token": "K7M2XQ9",
"pool_line_number": "<string>",
"pairing_expires_at": "<string>",
"instructions_url": "<string>",
"metadata": {}
},
"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>"
}{
"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>"
}Start a trial
Starts a trial on a pool line and returns the pairing code that the prospect texts to that line.
curl --request POST \
--url https://api.isnap.ai/v1/trial/init \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"max_outbound_without_inbound": 10,
"welcome_message": "You are connected to Acme. Reply here at any time.",
"footer": "Sent free via Acme",
"metadata": {
"crm_account_id": "acc_123"
}
}
'import requests
url = "https://api.isnap.ai/v1/trial/init"
payload = {
"max_outbound_without_inbound": 10,
"welcome_message": "You are connected to Acme. Reply here at any time.",
"footer": "Sent free via Acme",
"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({
max_outbound_without_inbound: 10,
welcome_message: 'You are connected to Acme. Reply here at any time.',
footer: 'Sent free via Acme',
metadata: {crm_account_id: 'acc_123'}
})
};
fetch('https://api.isnap.ai/v1/trial/init', 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/trial/init",
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([
'max_outbound_without_inbound' => 10,
'welcome_message' => 'You are connected to Acme. Reply here at any time.',
'footer' => 'Sent free via Acme',
'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/trial/init"
payload := strings.NewReader("{\n \"max_outbound_without_inbound\": 10,\n \"welcome_message\": \"You are connected to Acme. Reply here at any time.\",\n \"footer\": \"Sent free via Acme\",\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/trial/init")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"max_outbound_without_inbound\": 10,\n \"welcome_message\": \"You are connected to Acme. Reply here at any time.\",\n \"footer\": \"Sent free via Acme\",\n \"metadata\": {\n \"crm_account_id\": \"acc_123\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.isnap.ai/v1/trial/init")
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 \"max_outbound_without_inbound\": 10,\n \"welcome_message\": \"You are connected to Acme. Reply here at any time.\",\n \"footer\": \"Sent free via Acme\",\n \"metadata\": {\n \"crm_account_id\": \"acc_123\"\n }\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"trial_id": "trl_4Lp8Rn2xY7wQ9mK3vB5nH8dF2",
"token": "K7M2XQ9",
"pool_line_number": "<string>",
"pairing_expires_at": "<string>",
"instructions_url": "<string>",
"metadata": {}
},
"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>"
}{
"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. A trial key returns
401 unauthorized. - Line-scoped keys: the list of lines of a line-scoped key is not applied.
- Test keys: an
isnap_test_account key starts a real trial: see Test keys. Idempotency-Key: not honored. For a wholesale partner, a repeated call starts another trial. A direct account receives409 trial_already_active, a repeat of a call whose response was lost included. See How a trial works.- Events: none.
trial.linkedis sent later, when the prospect pairs: see Events. - Secret:
tokenis the pairing code. The response carriesCache-Control: no-store, whatever its status. See How a trial works. - Limit: a direct account has one live trial at a time: see Limits on live trials.
Errors
| Status | error.code | When |
|---|---|---|
| 400 | validation_failed | An unknown field, a value out of range, or a metadata over 20 keys or 8,192 bytes. |
| 409 | trial_already_active | A direct account already has a live trial. Revoke it first. If you lost its trial_id before the prospect paired, the limit frees when its pairing window ends, 15 minutes after the call. |
| 503 | line_pool_exhausted | No pool line is available. No trial is started: retry up to 2 times with exponential backoff, then write to support@isnap.ai with the trace_id and request_id of the response. |
| 503 | pairing_code_unavailable | iSnap could not allocate a pairing code. No trial is started: call again. |
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
Options of a trial. Every field is optional.
Number of messages the trial key can send in a row without a reply, a reaction or a read receipt from the prospect. When the trial runs on an iMessage line, a read does not count: only a reply or a reaction does. From 1 to 100. Default: 10. The send that reaches this number succeeds and makes the trial dormant.
1 <= x <= 10010
Text of the confirmation message that the prospect receives once, when pairing succeeds. From 1 to 280 characters. Default: a confirmation text written by iSnap. The message is not retried when its delivery fails, and it does not count as a send of the trial.
1 - 280"You are connected to Acme. Reply here at any time."
Text appended, after a blank line, to every message the trial key sends, in place of the footer of iSnap. From 1 to 300 characters. Default: Sent for free with iSnap - isnap.ai. A footer cannot be turned off. Characters outside GSM-7 make each SMS segment shorter.
1 - 300"Sent free via Acme"
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 trial, waiting for the prospect to send the pairing code.
Always true on a success response.
true A trial that was just started.
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.