curl --request POST \
--url https://api.isnap.ai/v1/messages \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"line_id": "<string>",
"to": "<string>",
"body": "<string>",
"channel": "auto",
"attachments": [],
"effect": {
"type": "bubble"
},
"reply_to_message_id": "<string>",
"use_typing_indicator": true,
"ignore_quiet_hours": true,
"metadata": {
"crm_account_id": "acc_123"
}
}
'import requests
url = "https://api.isnap.ai/v1/messages"
payload = {
"line_id": "<string>",
"to": "<string>",
"body": "<string>",
"channel": "auto",
"attachments": [],
"effect": { "type": "bubble" },
"reply_to_message_id": "<string>",
"use_typing_indicator": True,
"ignore_quiet_hours": True,
"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({
line_id: '<string>',
to: '<string>',
body: JSON.stringify('<string>'),
channel: 'auto',
attachments: [],
effect: {type: 'bubble'},
reply_to_message_id: '<string>',
use_typing_indicator: true,
ignore_quiet_hours: true,
metadata: {crm_account_id: 'acc_123'}
})
};
fetch('https://api.isnap.ai/v1/messages', 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/messages",
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([
'line_id' => '<string>',
'to' => '<string>',
'body' => '<string>',
'channel' => 'auto',
'attachments' => [
],
'effect' => [
'type' => 'bubble'
],
'reply_to_message_id' => '<string>',
'use_typing_indicator' => true,
'ignore_quiet_hours' => true,
'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/messages"
payload := strings.NewReader("{\n \"line_id\": \"<string>\",\n \"to\": \"<string>\",\n \"body\": \"<string>\",\n \"channel\": \"auto\",\n \"attachments\": [],\n \"effect\": {\n \"type\": \"bubble\"\n },\n \"reply_to_message_id\": \"<string>\",\n \"use_typing_indicator\": true,\n \"ignore_quiet_hours\": true,\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/messages")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"line_id\": \"<string>\",\n \"to\": \"<string>\",\n \"body\": \"<string>\",\n \"channel\": \"auto\",\n \"attachments\": [],\n \"effect\": {\n \"type\": \"bubble\"\n },\n \"reply_to_message_id\": \"<string>\",\n \"use_typing_indicator\": true,\n \"ignore_quiet_hours\": true,\n \"metadata\": {\n \"crm_account_id\": \"acc_123\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.isnap.ai/v1/messages")
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 \"line_id\": \"<string>\",\n \"to\": \"<string>\",\n \"body\": \"<string>\",\n \"channel\": \"auto\",\n \"attachments\": [],\n \"effect\": {\n \"type\": \"bubble\"\n },\n \"reply_to_message_id\": \"<string>\",\n \"use_typing_indicator\": true,\n \"ignore_quiet_hours\": true,\n \"metadata\": {\n \"crm_account_id\": \"acc_123\"\n }\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"id": "<string>",
"line_id": "<string>",
"direction": "outbound",
"kind": "message",
"to": "<string>",
"from": "<string>",
"body": "<string>",
"channel": "auto",
"service": "iMessage",
"status": "queued",
"effect": {
"type": "bubble",
"name": "slam"
},
"reply_to_message_id": "<string>",
"use_typing_indicator": true,
"metadata": {},
"attachments": [
{
"id": "<string>",
"content_type": "<string>",
"filename": "<string>",
"size_bytes": 2,
"duration_ms": 1
}
],
"reactions": [
{
"reaction_type": "love",
"reaction_emoji": "<string>",
"from_handle": "<string>",
"direction": "outbound",
"created_at": "<string>"
}
],
"scheduled_for": "<string>",
"schedule_reason": "<string>",
"reply_lane": true,
"ignore_quiet_hours": true,
"queue_info": {
"queue_position": 1,
"is_new_contact": true,
"daily_new_contacts_used": 1,
"daily_new_contact_limit": 1,
"daily_known_contacts_used": 1,
"daily_known_contact_limit": 1,
"daily_messages_used": 1,
"daily_total_message_limit": 1,
"reply_lane": true,
"daily_replies_used": 1,
"daily_reply_limit": 1,
"messages_ahead_in_queue": 1,
"daily_slot_of": "<string>",
"target_activity_hour": 11,
"next_slot_available_at": "<string>",
"last_new_contact_sent_at": "<string>",
"min_inter_new_contact_seconds": 1,
"jitter_applied_seconds": 1
},
"created_at": "<string>",
"queued_at": "<string>",
"sent_at": "<string>",
"delivered_at": "<string>",
"read_at": "<string>",
"failed_at": "<string>",
"error_code": "<string>",
"error_message": "<string>",
"cancelled_at": "<string>"
},
"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>"
}{
"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>"
}Send a message
Sends one message to one phone number from one of your lines, and returns it as queued or held.
curl --request POST \
--url https://api.isnap.ai/v1/messages \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"line_id": "<string>",
"to": "<string>",
"body": "<string>",
"channel": "auto",
"attachments": [],
"effect": {
"type": "bubble"
},
"reply_to_message_id": "<string>",
"use_typing_indicator": true,
"ignore_quiet_hours": true,
"metadata": {
"crm_account_id": "acc_123"
}
}
'import requests
url = "https://api.isnap.ai/v1/messages"
payload = {
"line_id": "<string>",
"to": "<string>",
"body": "<string>",
"channel": "auto",
"attachments": [],
"effect": { "type": "bubble" },
"reply_to_message_id": "<string>",
"use_typing_indicator": True,
"ignore_quiet_hours": True,
"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({
line_id: '<string>',
to: '<string>',
body: JSON.stringify('<string>'),
channel: 'auto',
attachments: [],
effect: {type: 'bubble'},
reply_to_message_id: '<string>',
use_typing_indicator: true,
ignore_quiet_hours: true,
metadata: {crm_account_id: 'acc_123'}
})
};
fetch('https://api.isnap.ai/v1/messages', 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/messages",
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([
'line_id' => '<string>',
'to' => '<string>',
'body' => '<string>',
'channel' => 'auto',
'attachments' => [
],
'effect' => [
'type' => 'bubble'
],
'reply_to_message_id' => '<string>',
'use_typing_indicator' => true,
'ignore_quiet_hours' => true,
'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/messages"
payload := strings.NewReader("{\n \"line_id\": \"<string>\",\n \"to\": \"<string>\",\n \"body\": \"<string>\",\n \"channel\": \"auto\",\n \"attachments\": [],\n \"effect\": {\n \"type\": \"bubble\"\n },\n \"reply_to_message_id\": \"<string>\",\n \"use_typing_indicator\": true,\n \"ignore_quiet_hours\": true,\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/messages")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"line_id\": \"<string>\",\n \"to\": \"<string>\",\n \"body\": \"<string>\",\n \"channel\": \"auto\",\n \"attachments\": [],\n \"effect\": {\n \"type\": \"bubble\"\n },\n \"reply_to_message_id\": \"<string>\",\n \"use_typing_indicator\": true,\n \"ignore_quiet_hours\": true,\n \"metadata\": {\n \"crm_account_id\": \"acc_123\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.isnap.ai/v1/messages")
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 \"line_id\": \"<string>\",\n \"to\": \"<string>\",\n \"body\": \"<string>\",\n \"channel\": \"auto\",\n \"attachments\": [],\n \"effect\": {\n \"type\": \"bubble\"\n },\n \"reply_to_message_id\": \"<string>\",\n \"use_typing_indicator\": true,\n \"ignore_quiet_hours\": true,\n \"metadata\": {\n \"crm_account_id\": \"acc_123\"\n }\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"id": "<string>",
"line_id": "<string>",
"direction": "outbound",
"kind": "message",
"to": "<string>",
"from": "<string>",
"body": "<string>",
"channel": "auto",
"service": "iMessage",
"status": "queued",
"effect": {
"type": "bubble",
"name": "slam"
},
"reply_to_message_id": "<string>",
"use_typing_indicator": true,
"metadata": {},
"attachments": [
{
"id": "<string>",
"content_type": "<string>",
"filename": "<string>",
"size_bytes": 2,
"duration_ms": 1
}
],
"reactions": [
{
"reaction_type": "love",
"reaction_emoji": "<string>",
"from_handle": "<string>",
"direction": "outbound",
"created_at": "<string>"
}
],
"scheduled_for": "<string>",
"schedule_reason": "<string>",
"reply_lane": true,
"ignore_quiet_hours": true,
"queue_info": {
"queue_position": 1,
"is_new_contact": true,
"daily_new_contacts_used": 1,
"daily_new_contact_limit": 1,
"daily_known_contacts_used": 1,
"daily_known_contact_limit": 1,
"daily_messages_used": 1,
"daily_total_message_limit": 1,
"reply_lane": true,
"daily_replies_used": 1,
"daily_reply_limit": 1,
"messages_ahead_in_queue": 1,
"daily_slot_of": "<string>",
"target_activity_hour": 11,
"next_slot_available_at": "<string>",
"last_new_contact_sent_at": "<string>",
"min_inter_new_contact_seconds": 1,
"jitter_applied_seconds": 1
},
"created_at": "<string>",
"queued_at": "<string>",
"sent_at": "<string>",
"delivered_at": "<string>",
"read_at": "<string>",
"failed_at": "<string>",
"error_code": "<string>",
"error_message": "<string>",
"cancelled_at": "<string>"
},
"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>"
}{
"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, or a trial key, which sends text only, from the trial’s line to the trial’s paired number: see Send with the trial key and With a trial key. See The send request.
- Line-scoped keys: a line-scoped key gets
403 forbiddenunlessline_idis in its list. - Test keys: a send with an
isnap_test_account key reaches a real recipient and counts against the same sending limits: see Test keys. Idempotency-Key: honored. The key belongs to the line, and a repeat returns the message already created, as it is now. The checks on the line, and on the trial with a trial key, run before the key is read: a refusal of a repeat does not mean that the first request was refused. See Retrying a send.- Events:
message.queued, ormessage.scheduledfor a held message, then the events of Following a message. - Personal data: the message carries the handles in
toandfrom, the text inbody, the attachment file names and yourmetadata. Request it only when needed, do not copy it into logs, tickets or other tools, and refer to a contact by an id of your own. - Quiet hours:
ignore_quiet_hours: truelets the message leave during the quiet hours of the line. Use it for a recipient of your own, such as your own phone number: the API does not check the recipient. The sending limits, the spacing and the order per recipient still apply, and a shared line ignores it. See Sending during quiet hours. - Response:
202means that iSnap accepted the message, never that it was sent.statusisqueued, orscheduledwhen iSnap holds the message: see The response and Held messages.queue_infois filled only in this response. - Headers: with an account API key, the
202carriesX-iSnap-Quota-RemainingandX-iSnap-Quota-Resets-At: see Headers on a send. - Rate limit: this operation and
GET /v1/messagesshare the message-operations limit, 60 requests per rolling 60 seconds per network address, in addition to the request-rate limit: see Rate limits.
Errors
| Status | error.code | When |
|---|---|---|
| 400 | validation_failed | A required field is missing, a field is too long, channel is not auto, more than 10 attachments, an unknown effect, metadata over 20 keys or 8,192 bytes, or neither body nor an attachment. |
| 400 | bad_request | to is not a valid phone number, or is an email address. |
| 400 | line_not_active | The line is neither active nor suspended. |
| 403 | forbidden | The request uses a line-scoped key, and line_id is not in its list. |
| 403 | line_suspended | The line is suspended. |
| 403 | outbound_first_forbidden | The line is inbound-only, and the recipient never wrote to it. |
| 404 | not_found | The line does not exist or is not yours, reply_to_message_id is unknown or was deleted, or an attachment id is not one your account created. |
| 409 | idempotency_conflict | The Idempotency-Key was already used on this line with other content. |
| 422 | reply_to_cross_line | reply_to_message_id is a message of another line. |
| 429 | minute_limit_exceeded, hourly_limit_exceeded, total_message_quota_exceeded, new_contact_quota_exceeded, known_contact_quota_exceeded | A sending limit is reached on a line set to refuse. See Refusals. |
| 429 | queue_full | The message would be held, and the line holds its maximum. See Maximum number of held messages. |
| 500 | internal_error | An unexpected error. It includes an Idempotency-Key longer than 255 characters, and the losing one of two simultaneous requests with the same new key: retry it with that key. |
| 503 | line_pool_exhausted | Shared line: no number can take a new contact. |
| 503 | quota_state_unavailable | Shared line: iSnap could not read the state of the line. Retry. |
With a trial key
A send with a trial key can also return these refusals:| Status | error.code | When |
|---|---|---|
| 400 | bad_request | to is not a valid phone number. An email address is refused. |
| 402 | trial_needs_inbound | The trial is dormant: see Unanswered-send limit. A repeat of the send that made the trial dormant returns it too: iSnap accepted that earlier message, which you read with GET /v1/messages. |
| 403 | trial_scope_violation | line_id or to is outside the trial, or reply_to_message_id names a message of another trial. |
| 403 | line_not_active | The pool line is not active. |
| 404 | not_found | reply_to_message_id is unknown. |
| 409 | idempotency_conflict | The Idempotency-Key was already used on the pool line with another body. |
| 422 | trial_attachments_unsupported | The request carries attachments. |
| 422 | reply_to_cross_line | reply_to_message_id names a message on another line. |
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
The message to send. It needs a non-empty body or at least one attachment.
The line that sends the message: line_ followed by 25 letters or digits. It must be a line of your account whose status is active.
^line_[0-9A-Za-z]{25}$Recipient phone number, 1 to 30 characters. E.164 is preferred; a number without a country code is read as a US number. iSnap normalizes it to E.164 and returns the normalized value in to of the message. An email address or an Apple ID returns 400 bad_request, even when POST /v1/lookup reports that it can receive iMessage. One request has one recipient: there is no group send.
1 - 30Message text, at most 5,000 characters. Required unless attachments is not empty. With a trial key, iSnap appends the footer of the trial to the text, after a blank line: the body of the message returned and the message the recipient receives both carry it.
5000Only auto is accepted, and it is the default: the line's device chooses the service.
auto Ordered list of at most 10 attachment ids (att_ followed by 25 letters or digits). On an iMessage line, the line's device sends only the first attachment and still reports the message sent: send one attachment per message. Create each attachment with POST /v1/attachments, upload the file, and wait until GET /v1/attachments/{id} shows status: ready: an attachment that is not ready when the line's device takes the message is left out of the message, without an error. An id that does not exist, that belongs to another account, or that names a file received on an inbound message returns 404 not_found. Do not repeat an id: a request that lists the same id twice returns 500 internal_error, and nothing is sent. A request with no body and exactly one attachment whose content type starts with audio/ is sent as a voice note, with kind: voice.
10Attachment id: att_ followed by 25 letters or digits.
^att_[0-9A-Za-z]{25}$iMessage effect of the message: a bubble effect or a screen effect. iSnap passes it to the line's device and does not report whether the recipient saw it.
- Option 1
- Option 2
Show child attributes
Show child attributes
Id of the message this message replies to (msg_ followed by 25 letters or digits): a message on the same line, received or sent. An id that does not exist returns 404 not_found, including the id of a message iSnap has deleted. A message on another line, of your account or of another account, returns 422 reply_to_cross_line.
^msg_[0-9A-Za-z]{25}$Whether the line's device shows the typing indicator to the recipient before it sends this message. When omitted, the line's default_use_typing_indicator applies, which is true unless you changed it. Always false on a line that is not an iMessage line. The response returns the value in effect.
true to let this message leave during the quiet hours of the line: the hours whose weight is 0 in the line's activity_curve, counted in the recipient's local time. Use it for a recipient of your own, such as an alert to your own phone number. The default is false. The message still waits for the sending limits of the line, for the spacing between messages and behind an earlier message to the same recipient that iSnap holds. No effect on a shared line. The response returns the value in effect.
Your own keys and values for this message: at most 20 keys and 8,192 bytes once serialized as JSON, otherwise the API returns 400 validation_failed. iSnap stores the object as sent and returns it in metadata of the message, in every response and in the events of the message.
Show child attributes
Show child attributes
{ "crm_account_id": "acc_123" }
Response
The message, accepted as queued or scheduled. iSnap holds a message when a sending limit of the line is reached and quota_overflow_behavior of the line is queue, the default. A message is also held by the spacing between messages of the line, by quiet hours, and behind an earlier message to the same recipient that has not left. A 202 returned to an API key carries two headers: X-iSnap-Quota-Remaining, the number of new contacts the line can still message in the rolling 24 hours, and X-iSnap-Quota-Resets-At, the next midnight UTC. The limits are rolling, so that second header is not the time a full limit frees: read GET /v1/lines/{id}/quota.
Always true on a success response.
true A message sent or received by a line. The response of POST /v1/messages, the reads, the list items, the cancel response and the message field of the message.* events all carry this object. It has no chat id: the chat id is given by GET /v1/chats and by events. It carries personal data: the handles in to and from, the text in body, the file names of attachments, and what you put in metadata. Timestamps are ISO 8601 in UTC.
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.