Rules for an agent that calls the API
The API writes. One call can send a real message to a real person, take a line that is billed, or end a line for good. Anisnap_test_ account key is not a separate test environment: it acts on the same account, lines and billing as an isnap_live_ key.
What to do with an error:
Errors and rate limits lists the codes.
Writes that cost money or cannot be undone
No API key limits an agent to reads. Give an agent a key of its own, so that you can revoke it alone in the iSnap dashboard.
Personal data
These operations and events return personal data:
Handle it the same way everywhere:
- Request it only when needed.
- Do not copy it into logs, tickets or other tools.
- Refer to a contact by an id of your own.
- Line
metadatais readable by anyone who holds the line id, and it stays on a line that returns to the marketplace. Never put personal data or secrets in linemetadata. - Everything an operation returns lands in your context. Answer with the fields the question needs, and do not quote message text or handles that your user did not ask for.
- To read one contact’s messages, narrow the walk with
line_id,direction,kindandsince, and drop the other items without quoting them.
Writing a client
A checklist for a coding agent that writes an integration. Each item links to the page that states the rule.- Credential. Send
Authorization: Bearer <key>tohttps://api.isnap.ai. Read the key from the environment variableISNAP_API_KEY, never from the code. Call the API from a server. See Authentication. - Tests. Do not write a test that sends through the API: there is no simulated send. Replace the HTTP layer in tests. See Test keys.
- Operations. Take the method, the path, the credential and the account each operation needs from the operations table. Take the schemas from the OpenAPI document.
- Requests. Send
Content-Type: application/jsonwith every body. Fields are insnake_case. See Conventions. - Responses. Read the result from
data. Handle the two204responses and the body ofGET /v1/health, which have no envelope. See Conventions. - Errors. Branch on
error.code, never onerror.message. Keeptrace_idandrequest_idwith every failure. See Error format. - Retries. Retry a
429afterRetry-Afterseconds. Retry a500or a503up to 2 times, with exponential backoff. Do not retry any other4xx: fix the request. Retry automatically only whenretry_afteris 60 seconds or less: longer values come from the sending limits, the lookup limits and the trial revoke limit, and are scheduled, not slept. See Errors. - Writes. Retry a write only on an operation that honors
Idempotency-Key, with the key of the first attempt. Send retries one after the other. See Retrying safely. - Rate limits. Stay under the request-rate limit, 100 requests per rolling 60 seconds per network address, and under the message-operations limit, 60 requests per rolling 60 seconds per network address on
POSTandGET /v1/messagestogether. See Rate limits. - Lists. Follow
next_cursorwith the same filters on every page, and deduplicate on theidof the items: a list can restart, and an item can come back on a later page. Stop whenhas_moreisfalse.GET /v1/linespages by number. See List operations and Cursors. - Sending. A
202means accepted, not sent. Track the message to a final status, and handle a held message. See Sending messages, Message statuses and Held messages. - Line kinds and accounts. Read the five fields that name the kind of a line, and expect the refusals of an operation that is for wholesale partners only. See Line kinds and Accounts.
- Lines that change owner. A line you take lists the chats of its earlier owners, and events about their messages can reach you: ignore the chats and the events about messages older than the time the line became yours. Note that time when you get the line: no event announces a transfer. Before you transfer a line or let it return to the marketplace, export what you need from its chats. See A chat is never deleted, and Lines that change owner for the rule and for that time.
- Webhooks. Verify the signature of every delivery on the raw body, before you parse it. The HMAC key is the base64 decoding of the secret after
whsec_. Return a2xxwithin 10 seconds, and never410: it turns the subscription off. See Verifying signatures and Webhooks overview. - Duplicates. Deduplicate on
event_id. See Duplicates. - Order. Delivery order is not guaranteed. Order events by the timestamps inside
data, not by arrival. See Order. For message events, apply Building the status from events. - Missing events. Events do not announce every change, and the events feed holds only the events that an active, unsuspended webhook subscription of your account matched. Reconcile from the resource operations. See What events do not announce and Events feed.
- Unknown values. Ignore response fields, enum values and event types you do not know. See Versioning and compatibility.
- Identifiers and timestamps. Store an id as an opaque, case-sensitive string. Parse timestamps as ISO 8601 in UTC. See Identifiers and Timestamps.
- Personal data. Keep handles and message text out of logs. See Personal data.
The TypeScript SDK
@isnap/sdk wraps the operations of the API, verifies webhook signatures and types the responses: see the SDK overview. One rule matters to an agent: the SDK retries every method automatically, writes included, and by default adds an Idempotency-Key to every write. A client created with idempotencyKey: "manual" sends a key only when the call passes one, and still retries: a write without a key can then run twice. On an operation that ignores the key, a retry can run the operation twice. Pass { maxRetries: 0 } as the last argument of such a call: see SDK errors. To call a method again yourself, pass the key of the first call in idempotencyKey: by default, the SDK makes a new key for each call. Pass { maxRetries: 0 } to chats.shareContactCard and to trial.status too.
These docs for agents
/llms.txt, at the root of this site, lists its pages with their descriptions, in a form made for language models.- Each page of this site is also served as Markdown: add
.mdto its URL./llms-full.txtholds every page in one file. To learn one operation, read its reference page rather than the whole OpenAPI document, which runs to more than 200,000 characters. - To compute
sincefor a window that ends now, read the current time from your tool, ortimestampfromGET /v1/health, which needs no credential. - The OpenAPI document describes every operation and schema in machine-readable form. Its operations are served at
https://api.isnap.ai. - The operations table and the error tables are the two places to check before a call.