Notix
Email API

An email API you can follow from send to inbox.

One call sends a receipt, a reset link or a newsletter. Then every step it takes is in your logs, on the Emails page and at your webhook, so you never have to guess what happened to a message.

Your stack

Send with the language you already use

Three SDKs that set the key and the headers for you, and a plain JSON API for everything else. Each call returns an emailId you can look up later.

npm install notix-js
import { Notix } from "notix-js";

const notix = new Notix(process.env.NOTIX_API_KEY);

const { data, error } = await notix.emails.send({
  from: "Acme <orders@acme.com>",
  to: "amara@example.com",
  subject: "Your order is on its way",
  html: "<p>Your parcel left our warehouse today.</p>",
});

console.log(data?.emailId);

The same send also works over SMTP, with no code change at all. The full request and response are in the API reference.

Visibility

See what happened to every message

Logs for the requests you made, events for what happened after, and webhooks that tell your own system.

API request logs

Every call to the API is written to the Logs page with its status, the key that made it and the time, and kept for 30 days. So a failing call in staging is found in seconds, not in a support thread.

  • Filter by status, method, endpoint, source or API key
  • Keys, codes, email bodies and attachments are hidden before the log is saved
  • Read the same logs from the API with notix.logs.list()

Logs

Every API request, kept 30 days
RequestStatusKeyWhen
POST /v1/emails200Production09:41:02
POST /v1/emails/batch200Production09:40:55
POST /v1/emails422Staging09:38:12
PATCH /v1/emails/cm9x...200Production09:31:40
GET /v1/emails/cm9x...200Production09:30:03

Every event, on every email

Open any email on the Emails page and you see each step it took: queued, sent, delivered, opened, clicked, or the bounce and the reason for it. The same history is one notix.emails.get(id) away.

Your order is on its way

to amara@example.com
Delivered
EventDetailTime
QueuedAccepted by the API09:41:02
SentHanded to the receiving server09:41:02
DeliveredAccepted by gmail.com09:41:03
OpenedFirst open09:44:17

Webhooks your code can trust

Register a URL and Notix posts each event to it as it happens. Every delivery carries anX-Notix-Signature you check with your secret, and a failed delivery is tried again up to six times. Calls you missed can be sent again by hand from the console.

Check the signature in two lines
import { Notix } from "notix-js";

const notix = new Notix(process.env.NOTIX_API_KEY);
const hooks = notix.webhooks(process.env.NOTIX_WEBHOOK_SECRET);

// Throws if the signature or timestamp is wrong.
const event = hooks.constructEvent(await request.text(), { headers: request.headers });

All event types are on the webhooks page and in the webhooks guide.

A signed delivery to your endpoint
POST /hooks/notix HTTP/1.1
X-Notix-Event: email.delivered
X-Notix-Timestamp: 1791359263951
X-Notix-Signature: v1=5f2c9a...e41b

{
  "id": "call_8sd02k",
  "type": "email.delivered",
  "version": "2026-09-08",
  "createdAt": "2026-10-07T09:41:03.951Z",
  "teamId": 123,
  "attempt": 1,
  "data": {
    "id": "cm9x2k7f0001",
    "status": "DELIVERED",
    "from": "orders@acme.com",
    "to": ["amara@example.com"],
    "subject": "Your order is on its way",
    "occurredAt": "2026-10-07T09:41:03.951Z"
  }
}
Endpoints

One API for every kind of send

The parts of a sending system you would otherwise build yourself.

Schedule

Hold a message until a time you choose, then move it or cancel it before it goes.

scheduledAt

Batch

Send up to 100 different messages in one request, each with its own recipient and content.

100 per call

Attachments

Invoices and tickets as base64 files: up to 10 per email, 7 MB each.

10 files, 10 MB

Idempotency

Retry without fear. The same Idempotency-Key never sends the same email twice.

24 hours

Templates and variables

Send a saved template by its id and fill in {{firstName}} and friends from variables.

templateId

cc, bcc and reply-to

Up to 50 addresses across to, cc and bcc, a reply-to, and your own headers.

50 recipients

Schedule, move, cancel

A scheduled email waits in Notix, not in a cron job of yours. It shows on the Emails page as scheduled until it sends.

schedule.ts
const { data } = await notix.emails.send({
  from: "Acme <hello@acme.com>",
  to: "wanjiru@example.com",
  subject: "Your trial ends tomorrow",
  html: "<p>Here is what happens next.</p>",
  scheduledAt: "2026-10-08T09:00:00+03:00",
});

// Changed your mind? Move it or call it off before it goes.
await notix.emails.update(data.emailId, { scheduledAt: "2026-10-08T12:00:00+03:00" });
await notix.emails.cancel(data.emailId);

A batch from a template

One request, a hundred shipping notices, each filled in with its own name and tracking code. The template is the one your team edits in the console.

ship-orders.ts
await notix.emails.batch(
  orders.map((order) => ({
    from: "Acme <orders@acme.com>",
    to: order.email,
    templateId: "order-shipped",
    variables: { firstName: order.firstName, trackingCode: order.tracking },
  })),
);
Idempotency

Press send twice. It sends once.

Networks drop answers. With an idempotency key, the retry gets the first result back instead of a second email.

Try it

The first request sends. Every retry with the same key and the same body gets that answer back, marked as replayed. Change the body and keep the key, and the API refuses it, so a bug cannot reuse a key by accident.

  • Works on single sends, batches and SMS
  • Kept for 24 hours, keys up to 256 characters
  • In notix-js: emails.send(payload, { idempotencyKey })
POST /api/v1/emailsIdempotency-Key: order-4471
{
  "to": "amara@example.com",
  "subject": "Your receipt",
  ...
}
Responsesnone yet
Press send, then press it again.
Built in

The safety rails come with the key

100messages in one batch call
24 han idempotent result is kept
6tries for each webhook delivery
30 daysof API request logs

One suppression list

An address that bounced hard, complained or unsubscribed is not sent to again, from the API, SMTP or a broadcast.

Test without risk

A dry run checks a send and shows who it would reach, without sending anything. Test emails.

FAQ

Questions, answered

Which languages can I send from?
There are SDKs for Node.js and TypeScript (notix-js), Python (notix-sdk) and PHP (usenotix/notix-php). Everything else talks to the same JSON API over HTTPS with a bearer token, so Go, Ruby, Java and .NET work with their standard HTTP client.
How many emails can one batch call send?
Up to 100 messages in one request, each with its own recipient, subject, body or template. You get one emailId back per message.
What happens if my server retries a request?
Send an Idempotency-Key header (up to 256 characters) and Notix keeps the result for 24 hours. A retry with the same key and body gets the first answer back with Idempotent-Replayed: true, and nothing is sent twice. The same key with a different body is refused with a 409.
Can I schedule an email and cancel it later?
Yes. Pass scheduledAt as an ISO 8601 time with an offset. Until it goes out you can move it with an update call or cancel it, from the API or the Emails page in the console.
Can I send attachments?
Yes, up to 10 files per email as base64 content, 7 MB per file and 10 MB per email in total.
How do I know an email was delivered?
Three ways: read it back with a get call, open it on the Emails page to see each event, or register a webhook and receive email.sent, email.delivered, email.bounced, email.opened and the rest as they happen, each one signed.

Send your first email in five minutes.

Verify a domain, copy an API key, make one call. The free plan does not ask for a card.