Notix
Webhooks

Hear about every message the moment it changes.

Notix posts a signed event to your server when an email is delivered or bounces, a code is checked, a text lands or a customer writes back. Your app stays in step without asking over and over.

Event catalogue

40 events, one envelope

Every call has the same outer shape: an id, the type, the time and the event's own data. Pick a group to see its events and a sample payload.

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

Check every call in one line

Each webhook has its own secret. The SDKs check the signature and the timestamp, then hand you a typed event.

app/api/notix/route.ts
import { Notix } from "notix-js";

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

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

  if (event.type === "email.bounced") {
    await markAddressBad(event.data.to);
  }

  return new Response(null, { status: 200 });
}

No SDK in your language? The signature is an HMAC-SHA256 of the timestamp and the raw body. The verify guide shows it by hand.

Delivery

Calls that get through, and a log when they do not

A short outage on your side does not lose events.

Six tries on a doubling clock

If your endpoint answers with anything but a 2xx, takes longer than 10 seconds or cannot be reached, Notix tries again after about 5, 10, 20, 40 and 80 seconds. A retry carriesX-Notix-Retry: true and the same call id.

  • Every call kept for 30 days, with your server's answer
  • Send a failed call again with one press
  • A webhook that keeps failing is turned off, not left hammering your server

acme.com/hooks/notix

All events · last 24 hours
Active
Calls4,812
Retries37
Failed2
EventStatusAnswerWhen
email.deliveredDelivered200 · 84 ms09:41:04
contact.unsubscribedDelivered200 · 61 ms09:40:51
email.bouncedFailed50309:12:30
webhook.testDelivered200 · 70 ms08:58:02

Run webhooks from code

Everything on the Webhooks page is in the API too: create, change, pause, test, delete, read the call log and retry a call. An empty eventTypes list sends every event.

  • Limit a webhook to some of your domains
  • The owner and admins get an email when a webhook is added, changed or deleted
Create a webhook
const { data, error } = await notix.webhookEndpoints.create({
  url: "https://acme.com/hooks/notix",
  eventTypes: ["email.delivered", "email.bounced", "contact.unsubscribed"],
});

// Shown once. Keep it as NOTIX_WEBHOOK_SECRET.
console.log(data?.secret);
Test, replay and rotate
// Send a signed webhook.test event to the saved URL.
await notix.webhookEndpoints.test(webhookId);

// Read the delivery log and send a failed call again.
const { data: calls } = await notix.webhookEndpoints.listCalls({ webhookId, status: "FAILED" });
await notix.webhookEndpoints.retryCall(callId);

// Leaked a secret? Rotate it. The old one stops at once.
await notix.webhookEndpoints.rotateSecret(webhookId);
Built in

Safe by default

40event types to choose from
6tries for each call
10 sfor your server to answer
30 daysof delivery history

Public HTTPS only

Notix refuses localhost, raw IP addresses and private networks, and checks the address again before every call.

One secret per webhook

Shown once when you create it. Rotate it whenever you like; the old one stops at once.

Test before you rely on it

Press Send a test event and a signed webhook.test call lands on your URL and in the log.

FAQ

Questions, answered

Which events can a webhook receive?
40 event types: every step of an email from queued to clicked, bounces and complaints, contacts, domains, one-time codes, SMS, received mail, automations, broadcasts and a few account events. Pick the ones you want, or leave the list empty to get them all.
How do I know a call really came from Notix?
Every call carries an X-Notix-Signature header: v1= and an HMAC-SHA256 of the timestamp and the raw body, made with your webhook's secret. The SDKs for Node.js, Python and PHP check it in one line and reject old timestamps.
What happens when my endpoint is down?
Notix tries each call up to six times. The first try is at once, then the wait doubles: about 5, 10, 20, 40 and 80 seconds. A call that fails every try is marked failed, and you can send it again from the console or the API.
Can I see what was sent and how my server answered?
Yes. Each webhook has a delivery log that keeps calls for 30 days. Open a call to see the event data, your endpoint's status code, how long it took and the start of its answer.
What if a secret leaks?
Rotate it from the webhook's Actions menu or with the API. The old secret stops working at once, and each webhook has its own secret, so one leak never touches another endpoint.
Can the same event arrive twice?
It can, for example when your server got the call but answered too late. The call id stays the same on every try, so store it and skip one you have already handled.

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.