Emails

Send, retrieve, and manage individual emails through the Txtly API.

Send Email

POST
/v1/emails

Send a single email message. Returns the email object with a unique ID.

Parameters

ParameterTypeDescription
fromrequiredstringSender email address
torequiredstring[]Array of recipient email addresses
subjectrequiredstringEmail subject line
htmlstringHTML email body
textstringPlain text email body
ccstring[]Carbon copy recipients
bccstring[]Blind carbon copy recipients
replyTostringReply-to email address
scheduledAtstring (ISO 8601)Schedule email for future delivery
headersobjectCustom email headers as key-value pairs
tagsobjectKey-value pairs for organization and tracking
templateIdstringID of a published template to use for the email body
templateVariablesobjectKey-value pairs to interpolate into the template (e.g. {"first_name": "Alice"})
attachmentsobject[]Array of file attachments. Each requires filename and base64-encoded content

Example Request

curl -X POST https://api.txtly.com.au/v1/emails \
  -H "Authorization: Bearer tx_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "noreply@example.com",
    "to": ["user@example.com"],
    "subject": "Welcome to Txtly",
    "html": "<h1>Hello</h1><p>Welcome aboard!</p>",
    "text": "Hello. Welcome aboard!",
    "tags": {"signup": "true"}
  }'

Example Response

{
  "id": "d290f1ee-6c54-4b01-90e6-d701748f0851",
  "from": "noreply@example.com",
  "to": ["user@example.com"],
  "cc": null,
  "bcc": null,
  "subject": "Welcome to Txtly",
  "html": "<h1>Hello</h1><p>Welcome aboard!</p>",
  "text": "Hello. Welcome aboard!",
  "status": "sent",
  "scheduledAt": null,
  "createdAt": "2026-03-21T10:30:00Z"
}

Immediate sends are dispatched synchronously and return with status sent. When scheduledAt is set, the email is stored with status scheduled and dispatched later by the scheduler.

Send Batch Emails

POST
/v1/emails/batch

Send up to 100 emails in a single request. Each email is sent synchronously through the same pipeline as the single send endpoint.

Parameters

ParameterTypeDescription
emailsrequiredobject[]Array of email objects with same parameters as single email endpoint (max 100, or your plan's batch size limit)

Behavior

The whole batch is validated up front (request shape, domains, suppression list, daily rate limit), then each email is sent one by one via the same path as POST /v1/emails. The batch is all-or-nothing on validation, but if a send fails partway through, emails before the failing index have already been sent — the request returns 400 with the failing index and no further emails are attempted.

Example Request

curl -X POST https://api.txtly.com.au/v1/emails/batch \
  -H "Authorization: Bearer tx_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "emails": [
      {
        "from": "noreply@example.com",
        "to": ["user1@example.com"],
        "subject": "Hello User 1",
        "html": "<p>Welcome</p>"
      },
      {
        "from": "noreply@example.com",
        "to": ["user2@example.com"],
        "subject": "Hello User 2",
        "html": "<p>Welcome</p>"
      }
    ]
  }'

Example Response

{
  "data": [
    {
      "id": "d290f1ee-6c54-4b01-90e6-d701748f0851",
      "from": "noreply@example.com",
      "to": ["user1@example.com"],
      "cc": null,
      "bcc": null,
      "subject": "Hello User 1",
      "html": "<p>Welcome</p>",
      "text": null,
      "status": "sent",
      "scheduledAt": null,
      "createdAt": "2026-03-21T10:30:00Z"
    },
    {
      "id": "a1b2c3d4-5e6f-7890-abcd-ef1234567890",
      "from": "noreply@example.com",
      "to": ["user2@example.com"],
      "cc": null,
      "bcc": null,
      "subject": "Hello User 2",
      "html": "<p>Welcome</p>",
      "text": null,
      "status": "sent",
      "scheduledAt": null,
      "createdAt": "2026-03-21T10:30:00Z"
    }
  ]
}

Error Response

If an email fails validation or fails to send, the request fails with the index of the offending email:

{
  "error": "Email at index 1 failed to send: Domain 'example.org' not found. Add and verify the domain first.",
  "index": 1
}

List Emails

GET
/v1/emails

List sent emails with cursor-based pagination.

Query Parameters

ParameterTypeDescription
limitnumberResults per page (default: 20, max: 100)
cursorstringCursor for pagination (from previous response)
statusstringFilter by status: scheduled, sent, delivered, bounced, complained, delayed, cancelled
domainIdstring (UUID)Filter by sending domain ID
searchstringSearch by subject or from address

Example Response

{
  "data": [
    {
      "id": "d290f1ee-6c54-4b01-90e6-d701748f0851",
      "from": "noreply@example.com",
      "to": ["user@example.com"],
      "subject": "Welcome to Txtly",
      "status": "delivered",
      "domainName": "example.com",
      "sentAt": "2026-03-21T10:30:05Z",
      "createdAt": "2026-03-21T10:30:00Z"
    }
  ],
  "cursor": "eyJpZCI6Imxhc3RfaWQifQ==",
  "hasMore": true,
  "total": 1342
}

total is the total number of emails matching the current filters, counted before pagination is applied — it stays constant as you page through results.

Get Email

GET
/v1/emails/{id}

Retrieve an email by ID.

Path Parameters

ParameterTypeDescription
idrequiredstringEmail ID

Example Response

{
  "id": "d290f1ee-6c54-4b01-90e6-d701748f0851",
  "from": "noreply@example.com",
  "to": ["user@example.com"],
  "cc": null,
  "bcc": null,
  "subject": "Welcome to Txtly",
  "html": "<h1>Hello</h1><p>Welcome aboard!</p>",
  "text": "Hello. Welcome aboard!",
  "status": "delivered",
  "scheduledAt": null,
  "createdAt": "2026-03-21T10:30:00Z"
}

Get Email Events

GET
/v1/emails/{id}/events

Retrieve all lifecycle events for a specific email.

Path Parameters

ParameterTypeDescription
idrequiredstringEmail ID

Example Response

Returns an array of events, newest first. Each event includes a data object containing the raw provider payload for that event (e.g. SES bounce type and diagnostic code), or null when no provider payload is available.

[
  {
    "id": "f2a3b4c5-6789-01bc-def0-2345678901bc",
    "type": "bounced",
    "createdAt": "2026-03-21T10:30:15Z",
    "data": {
      "notificationType": "Bounce",
      "mail": { "messageId": "ses-message-id" },
      "bounce": {
        "bounceType": "Permanent",
        "bouncedRecipients": [
          { "emailAddress": "user@example.com", "diagnosticCode": "smtp; 550 5.1.1 user unknown" }
        ]
      }
    }
  },
  {
    "id": "e1f2a3b4-5678-90ab-cdef-1234567890ab",
    "type": "sent",
    "createdAt": "2026-03-21T10:30:05Z",
    "data": null
  }
]

Cancel Email

POST
/v1/emails/{id}/cancel

Cancel a scheduled email before it is sent. Only emails with status 'scheduled' can be cancelled.

Path Parameters

ParameterTypeDescription
idrequiredstringEmail ID

Example Request

curl -X POST https://api.txtly.com.au/v1/emails/d290f1ee-.../cancel \
  -H "Authorization: Bearer tx_your_api_key"

Example Response

{
  "id": "d290f1ee-6c54-4b01-90e6-d701748f0851",
  "from": "noreply@example.com",
  "to": ["user@example.com"],
  "cc": null,
  "bcc": null,
  "subject": "Welcome to Txtly",
  "html": "<h1>Hello</h1>",
  "text": null,
  "status": "cancelled",
  "scheduledAt": "2026-04-01T09:00:00Z",
  "createdAt": "2026-03-21T10:30:00Z"
}

Reschedule Email

PATCH
/v1/emails/{id}

Update the scheduled send time of a scheduled email.

Parameters

ParameterTypeDescription
scheduledAtrequiredstring (ISO 8601)New scheduled send time (must be in the future)

Example Request

curl -X PATCH https://api.txtly.com.au/v1/emails/d290f1ee-... \
  -H "Authorization: Bearer tx_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"scheduledAt": "2026-04-02T09:00:00Z"}'

Example Response

{
  "id": "d290f1ee-6c54-4b01-90e6-d701748f0851",
  "from": "noreply@example.com",
  "to": ["user@example.com"],
  "cc": null,
  "bcc": null,
  "subject": "Welcome to Txtly",
  "html": "<h1>Hello</h1>",
  "text": null,
  "status": "scheduled",
  "scheduledAt": "2026-04-02T09:00:00Z",
  "createdAt": "2026-03-21T10:30:00Z"
}

Email Events

Emails generate events throughout their lifecycle. You can listen to these events via webhooks or retrieve them with the Get Email Events endpoint. Permanent (hard) bounces and complaints automatically add the recipient to your team's suppression list, blocking future sends to that address.

Event Types

  • email.sentEmail was accepted by the mail server
  • email.deliveredEmail was successfully delivered to recipient
  • email.delivery_delayedDelivery was delayed but will be retried
  • email.bouncedEmail bounced at recipient server
  • email.complainedRecipient marked email as spam
  • email.openedRecipient opened the email
  • email.clickedRecipient clicked a link in the email