Emails
With these endpoints, an external system sends one email to one recipient through SquadOS and tracks its delivery. Use them for emails triggered by events in your system, such as a sign-up confirmation, an issued invoice or a meeting reminder. To send to a whole list, use campaigns in the dashboard.
Sending follows the same path as automation emails: SquadOS honours unsubscribes and bounces, charges email credits and records delivery.
Every endpoint requires the Authorization: Bearer pk_... header. When sending, also send Content-Type: application/json.
Base URL: https://api.squados.io/v1
See Authentication to get your key, and Errors for the code reference.
Which token to use
Section titled “Which token to use”- Full access sends from any sender of the organization.
- Send emails only sends only from the senders checked under Allowed senders when the token was generated, and reaches only these two endpoints. Prefer this scope for an integration that only sends email.
POST /emails
Section titled “POST /emails”Queues an email to one recipient. Sending is asynchronous: the response confirms the email entered the queue, and the final status is read with GET /emails/{id}.
Body
| Field | Type | Required | Description |
|---|---|---|---|
from | string | Yes | Address of one of the organization’s senders, such as hello@yourcompany.com. Case does not matter. |
to | string | Yes | A single destination address. |
subject | string | Yes | Subject, up to 300 characters. |
html | string | One of the two | HTML body, sent as you wrote it. Up to 200,000 characters. |
text | string | One of the two | Plain-text body. Up to 200,000 characters. |
Send html, text or both:
textonly: SquadOS builds the HTML from the text’s paragraphs;htmlonly: the HTML goes as you wrote it, with variables filled in and the footer added;- both: the HTML is the main body and the text becomes the plain-text version of the same email.
Keep HTML under 100 KB: providers such as Gmail clip larger messages.
curl -X POST "https://api.squados.io/v1/emails" \ -H "Authorization: Bearer pk_your_key_here" \ -H "Content-Type: application/json" \ -d '{ "from": "hello@yourcompany.com", "to": "customer@example.com", "subject": "Your sign-up is confirmed", "html": "<p>Hi {{contact.first_name | \"there\"}}! Your account is active.</p>", "text": "Hi! Your account is active." }'Response — 202 Accepted
{ "id": "11111111-1111-4111-8111-111111111111", "status": "queued", "from": "hello@yourcompany.com", "to": "customer@example.com"}Keep the id to check delivery.
What happens to the recipient
Section titled “What happens to the recipient”- The recipient becomes a contact of the organization: SquadOS creates the contact when the address does not exist yet. Unsubscribes, bounces and send history work through it.
- People who unsubscribed or hard-bounced do not receive it: the API refuses the send before queuing it.
- The email goes out with the SquadOS footer: the organization’s name and address and a link for the person to manage what they receive.
Personalization
Section titled “Personalization”The subject and body accept three contact variables:
| Variable | Becomes |
|---|---|
{{contact.first_name}} | The contact’s first name |
{{contact.name}} | The contact’s full name |
{{contact.email}} | The contact’s address |
For when the contact has no name, add a fallback after |: {{contact.first_name | "there"}}. Any other variable between {{ }} gets the send refused with 400 and reason: "unknown_merge_tags", with the unknown variables in tags.
Send errors
Section titled “Send errors”The API refuses in the order of what you can fix: body, sender, token permission, domain, organization sending, recipient and credits.
| Status | code | reason | When |
|---|---|---|---|
| 400 | invalid_request | — | Invalid body: from or to is not a valid address, to has more than one address, subject is missing, both html and text are missing, or a field is over its limit. The field comes in field. |
| 400 | invalid_request | unknown_merge_tags | Unknown variable in the subject or body. The list comes in tags. |
| 403 | forbidden | sender_not_allowed | A Send emails only token using a sender that is not among its allowed senders. |
| 403 | forbidden | email_module_blocked | The organization cannot send email right now. The reason comes in blocked_reason: plan (the plan does not include email), not_activated, paused, disabled or setup_failed. |
| 403 | forbidden | insufficient_credits | The organization does not have enough email credits. |
| 404 | not_found | sender_not_found | from is not one of the organization’s senders. |
| 409 | conflict | sender_domain_not_verified | The sender’s domain is not verified yet. |
| 409 | conflict | recipient_suppressed | The recipient unsubscribed or bounced and cannot receive emails. The reason comes in suppression_reason: hard_bounce, complaint, soft_bounce_streak, unsubscribe or manual. |
| 409 | conflict | contact_conflict | The address belongs to a contact with an identity conflict in the organization. |
{ "error": "The sender domain is not verified yet", "code": "conflict", "reason": "sender_domain_not_verified", "field": "from"}GET /emails/{id}
Section titled “GET /emails/{id}”Reads the status of an email sent through the API.
curl "https://api.squados.io/v1/emails/11111111-1111-4111-8111-111111111111" \ -H "Authorization: Bearer pk_your_key_here"Response — 200 OK
{ "id": "11111111-1111-4111-8111-111111111111", "status": "delivered", "to": "customer@example.com", "subject": "Your sign-up is confirmed", "error_code": null, "created_at": "2026-10-25T12:00:00Z", "sent_at": "2026-10-25T12:00:04Z", "updated_at": "2026-10-25T12:00:09Z"}| Field | Type | Description |
|---|---|---|
id | uuid | The id returned when sending. |
status | string | Delivery state. See the table below. |
to | string or null | Recipient. |
subject | string | Subject sent. |
error_code | string or null | Failure code reported by the provider, when there is one. |
created_at | date-time | When the send was received. |
sent_at | date-time or null | When the email went out. |
updated_at | date-time | Last status change. |
status | Meaning |
|---|---|
queued | In the queue, not sent yet. |
sent | Sent and accepted by the sending provider. |
delivered | The recipient’s server confirmed delivery. |
bounced | Bounced by the recipient’s server. |
complained | The recipient marked it as spam. |
failed | Could not be sent. See error_code. |
suppressed | Not sent because the recipient can no longer receive emails. |
Poll at intervals, not in a tight loop: delivery usually takes from seconds to a few minutes.
An invalid id, one from another organization, or one for an email not sent through the API returns 404 not_found. A Send emails only token only sees emails sent from its allowed senders; the rest also return 404.