Skip to content
simailDocsv0

Integrate

SDKs (TypeScript / Python)

The official TypeScript and Python clients for the simail API — installation, configuration, idempotent sends and error handling.

docs.simail.ai/sdk

Both SDKs are thin, dependency-free clients over the REST API. They read the key from your code (load it from SIMAIL_API_KEY), set the headers for you and turn problem+json errors into exceptions with the fields an agent needs. Resource methods are generated from the OpenAPI document at GET https://api.simail.ai/v0/openapi.json, so they always match the API reference; every client also exposes a generic request() for any endpoint.

npm install @simail/sdk

Works in Node 22 and later, Cloudflare Workers and other runtimes with a standard fetch. No runtime dependencies. Use it on a server, never in a browser: it needs your API key.

import { Simail, SimailApiError } from "@simail/sdk";
const simail = new Simail({ apiKey: process.env.SIMAIL_API_KEY });
// Call this first: during the private beta, sign-up is closed.
const beta = await simail.beta();
// Any endpoint through request(method, path, body?, { idempotencyKey? })
const inbox = await simail.request("POST", "/v0/inboxes", { username: "shop-helper", client_id: "shop-helper" }, { idempotencyKey: "create-shop-helper" });
try {
await simail.request(
"POST",
"/v0/inboxes/shop-helper@simail.email/messages/msg_…/reply",
{ text: "Thanks! Your order shipped today." },
{ idempotencyKey: "reply-msg_…-1" },
);
} catch (e) {
if (e instanceof SimailApiError && !e.retryable) {
// e.status, e.code ("thread_locked", "send_blocked", …), e.requestId, e.body (full problem+json)
}
throw e;
}
OptionDefault
apiKeynone (only beta() works without a key)
baseUrlhttps://api.simail.ai
fetchthe global fetch (pass your own for proxies or tests)
userAgentsimail-sdk-ts/<version>
pip install simail

Python 3.10 or later, standard library only.

import os
from simail import Simail, SimailApiError
simail = Simail(api_key=os.environ["SIMAIL_API_KEY"])
simail.beta()
try:
simail.request(
"POST",
"/v0/inboxes/shop-helper@simail.email/messages/msg_…/reply",
{"text": "Thanks! Your order shipped today."},
idempotency_key="reply-msg_…-1",
)
except SimailApiError as e:
if not e.retryable:
print(e.status, e.code, e.request_id) # e.body has the full problem+json
raise

Simail(api_key=None, base_url="https://api.simail.ai"); requests time out after 30 seconds.

Both SDKs raise SimailApiError for any non-2xx response:

FieldFrom
statusHTTP status
codeproblem+json code (see Errors)
retryableproblem+json retryable
requestId / request_idrequest_id, also in the x-request-id header
bodythe whole problem+json object, including human_message, reasons or reason when present

The SDKs do not retry on their own, so a send is never repeated behind your back. Retry only when retryable is true, after Retry-After, with the same idempotency key. See Idempotency.

Never hard-code a key and never pass one through a prompt. Load it from the environment or your secret manager, and give each agent its own inbox-scoped key (Authentication).