AI integration

Wire up email sending for AI agents

A machine-readable path for coding agents and assistants that need to add transactional email to someone else's project — what to call, in what order, and which checks to run before every send.

Download OpenAPI 3.1

Before you write any code

  • Ask the user for a project API key, or have them create a sandbox key at https://app.srs-postline.com/en/login — never invent, guess, or reuse a key from another project.
  • Put the key in a server-side environment variable. Do not place it in frontend code, a mobile app bundle, a public repo, or a committed .env file.
  • Use an srs_live_ key. Before domain verification, send from sandbox@srs-postline.com only to a project member; verified domains may send externally within plan quotas.
  • Read /llms.txt and openapi/postline.yaml before generating request code; do not guess field names or endpoints.

Minimal send

POST /v1/emails
Authorization: Bearer srs_live_...
Idempotency-Key: <stable-id-per-logical-send>
Content-Type: application/json

{
  "from": "Sender Name <info@example.com>",
  "to": ["user@example.net"],
  "subject": "Subject",
  "html": "<p>Body</p>",
  "text": "Body"
}

Checks to run before every send

  • Always send an Idempotency-Key derived from the triggering action (order ID, event ID) so retries cannot double-send.
  • Never put OTP codes, password-reset tokens, or other secrets in a field that gets logged or forwarded outside the message body.
  • Request the narrowest API key scope the task needs (emails:send is enough for sending; do not ask for domains:write or api_keys:write unless the task requires it).
  • Cap recipients per call at 100. Attachments and custom headers are not accepted by the current API; reject or link files instead of implying they were attached.
  • Do not silently retry on 4xx responses. Only 429 and 503 are safe to retry, and only with backoff.

Handle every response code

  • 202 — queued, not delivered. Store the returned id if you need to look up status later.
  • 400 — invalid payload; fix the request, do not retry unchanged.
  • 401 — invalid or expired key; stop and surface this to the user, do not fabricate a new key.
  • 403 — missing scope or the sending domain is not verified yet; tell the user to verify the domain before continuing.
  • 422 — recipient is suppressed (past bounce/complaint); do not retry that recipient.
  • 429 — rate limited; back off and retry later, do not loop tightly.
  • 503 — queue unavailable; retry with backoff, do not fall back to an unofficial transport.

If the task includes receiving events

Register a webhook endpoint over HTTPS only. Recompute the signature yourself before trusting any payload; do not skip verification because a request 'looks internal'.

signature = HMAC-SHA256(webhook_secret, timestamp + "\0" + event_id + "\0" + raw_body)

compare to header Postline-Signature (constant-time compare)
reject if Postline-Timestamp is outside your allowed window
store event_id and process each event exactly once

Machine-readable references

  • /llms.txt — condensed index of these rules for agent context windows.
  • /openapi/postline.yaml — full OpenAPI 3.1 schema for every endpoint.
  • /en/api/ — human API reference.
  • /en/webhooks/ — webhook signature and retry details.

Current access model

Current dashboard keys use srs_live_. Before a customer From-domain is verified, use the shared sandbox sender only for project-member recipients. After DNS verification, external sending is governed by plan quotas, suppression, recipient throttles, and abuse controls. A 202 response means queued, not delivered.

Integration resources

Use the copy-paste guide for humans and AI agents, and treat OpenAPI as the field-level source of truth.