curl --request GET \
--url https://api.isnap.ai/v1/messages \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.isnap.ai/v1/messages"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
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 => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.isnap.ai/v1/messages"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.isnap.ai/v1/messages")
.header("Authorization", "Bearer <token>")
.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::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"items": [
{
"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>"
}
],
"has_more": true,
"next_cursor": "<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>"
}List messages
Lists the inbound and outbound messages that iSnap keeps, newest first, with filters and a cursor.
curl --request GET \
--url https://api.isnap.ai/v1/messages \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.isnap.ai/v1/messages"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
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 => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.isnap.ai/v1/messages"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.isnap.ai/v1/messages")
.header("Authorization", "Bearer <token>")
.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::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"items": [
{
"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>"
}
],
"has_more": true,
"next_cursor": "<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>"
}- Credential: an API key, or a trial key, which lists only the messages of its trial.
- Line-scoped keys: a line-scoped key gets only the messages of the lines of its list. A
line_idoutside the list returns an empty page. - Events: none.
- Personal data: the items carry handles, message text, attachment file names and
metadata. Request them only when needed, do not copy them into logs, tickets or other tools, and refer to a contact by an id of your own. See Personal data. - Pagination: a cursor, valid only with the
sort,orderand filters it was issued for. A cursor that cannot be read restarts the list from the first page, with200. See Cursors. - Retention: a message is listed until iSnap deletes it, at least 72 hours after it recorded it.
sinceanduntilbound that recording time: see Timestamps in queries. - Reaction entries: an item with
kind: reactiondoes not say which message it reacts to. See Listing messages. - Rate limit: this operation and
POST /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 malformed line_id, status, direction, kind, sort, order, since, until or limit. |
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.
Query Parameters
Only the messages of this line (line_ followed by 25 letters or digits). A line that does not exist, or that is not a line of your account, gives an empty page.
^line_[0-9A-Za-z]{25}$Only the messages with this status.
queued, scheduled, sent, delivered, read, failed, cancelled outbound: only the messages the line sent. inbound: only the messages the line received.
outbound, inbound Inclusive lower bound on created_at: an ISO 8601 timestamp with a UTC offset, for example 2026-01-15T14:00:00Z.
Inclusive upper bound on created_at: an ISO 8601 timestamp with a UTC offset, for example 2026-01-15T15:00:00Z.
message leaves out voice notes and reaction entries. voice and reaction return only those. Omit it for all kinds.
message, voice, reaction created_at, the default, orders by the time iSnap recorded each message. scheduled_for orders by planned departure, the value of the scheduled_for field: messages that have none, which are the inbound messages and the messages typed on the device of a line, come last in both directions.
created_at, scheduled_for desc or asc. When omitted: desc for sort=created_at (newest first) and asc for sort=scheduled_for (soonest first).
asc, desc The next_cursor of the previous page. Omit it for the first page. Send it with the same sort, order and filters as the request that returned it.
Number of messages per page, 1 to 100. The default is 25.
1 <= x <= 100Response
One page of messages.
Always true on a success response.
true One page of messages.
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.