Skip to main content
This page is for AI agents, and for the people who set them up. It gives the rules for an agent that calls the API while it works, a checklist for a coding agent that writes a client, and the places where an agent reads these docs. iSnap has no MCP server for its API. An agent calls the HTTP API, or uses the TypeScript SDK.

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. An isnap_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 metadata is 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 line metadata.
  • 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, kind and since, 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> to https://api.isnap.ai. Read the key from the environment variable ISNAP_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/json with every body. Fields are in snake_case. See Conventions.
  • Responses. Read the result from data. Handle the two 204 responses and the body of GET /v1/health, which have no envelope. See Conventions.
  • Errors. Branch on error.code, never on error.message. Keep trace_id and request_id with every failure. See Error format.
  • Retries. Retry a 429 after Retry-After seconds. Retry a 500 or a 503 up to 2 times, with exponential backoff. Do not retry any other 4xx: fix the request. Retry automatically only when retry_after is 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 POST and GET /v1/messages together. See Rate limits.
  • Lists. Follow next_cursor with the same filters on every page, and deduplicate on the id of the items: a list can restart, and an item can come back on a later page. Stop when has_more is false. GET /v1/lines pages by number. See List operations and Cursors.
  • Sending. A 202 means 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 a 2xx within 10 seconds, and never 410: 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 .md to its URL. /llms-full.txt holds 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 since for a window that ends now, read the current time from your tool, or timestamp from GET /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.