Your exports
People → Export to CSV, and a segment of unsubscribed people exported the same way.
CSVExport your contacts and your unsubscribes from Customer.io, upload both, and Notix brings them over in the right order. No key, nothing to revoke afterwards. Your Customer.io account keeps sending the whole time.
Load an example or paste your own send call: Node.js, Python, PHP or cURL. Anything that does not have a Notix equivalent is listed under the result.
import { Notix } from "notix-js";
const notix = new Notix(process.env.NOTIX_API_KEY);
const { data, error } = await notix.emails.send({
to: "amara@example.com",
templateId: "YOUR_NOTIX_TEMPLATE_ID",
variables: {
firstName: "Amara",
trackingCode: "KD-4471",
},
});
from with an address on a domain you have verified in Notix.The converter reads the code as text in your browser. It does not run it, store it or send it anywhere.
Upload the files Customer.io already lets you export. The Migration Center shows you what it found before it writes anything.
Templates come across from SendGrid only. From anywhere else, rebuild them in the editor or start from the 54 starter templates.
People → Export to CSV, and a segment of unsubscribed people exported the same way.
CSVThe uploaded files are kept for one hour while the import runs and dropped when it finishes.
Held 1 hourPaste an API key, or upload your contacts and unsubscribes as CSV. Nothing is written until you have seen what we found.
Every unsubscribe, bounce and complaint is written before the first contact, so nobody who opted out at your old provider can be emailed from Notix.
Contacts land in contact books you choose, with your custom fields mapped. Anyone suppressed arrives unsubscribed.
Publish our records alongside your old provider's. Both keep sending; DNS has room for both.
A four-week plan, 15% to 100%, so mailbox providers see a sender that grows steadily. Switch the old provider off at the end, not the start.
The console uses the same words throughout: Emails, Broadcasts, Automations, Templates, Audience, Metrics, Logs, Webhooks and API keys.
| In Customer.io | In Notix | Good to know |
|---|---|---|
| People | Audience | Attributes become contact properties. |
| Segments | Audience > Segments | Same idea, same place. |
| Subscription center topics | Audience > Topics | Same idea, same place. |
| Broadcasts | Broadcasts | Same idea, same place. |
| Campaigns | Automations | Email, delay, wait for event, if / else, update contact and add to segment steps. |
| Transactional messages | Templates, sent through the email API | Same idea, same place. |
| Deliveries and activity logs | Emails | Same idea, same place. |
| Sending domains | Domains | Same idea, same place. |
| API credentials | API keys | Same idea, same place. |
| Reporting webhooks | Webhooks | Same idea, same place. |
The same email, as you send it today and as you send it with Notix.
| Language | Customer.io | Notix |
|---|---|---|
| Node.js and TypeScript | customerio-node | notix-js |
| Python | customerio | notix-sdk |
| PHP and Laravel | Their HTTP API | usenotix/notix-php |
| Go, Ruby, Java, .NET and the rest | Their libraries, or the REST API | REST API (JSON over HTTPS) |
const { APIClient, SendEmailRequest, RegionUS } = require("customerio-node");
const api = new APIClient(process.env.CUSTOMERIO_APP_KEY, { region: RegionUS });
const request = new SendEmailRequest({
to: "amara@example.com",
transactional_message_id: "3",
message_data: { firstName: "Amara", trackingCode: "KD-4471" },
identifiers: { id: "user-4471" },
});
await api.sendEmail(request);
import { Notix } from "notix-js";
const notix = new Notix(process.env.NOTIX_API_KEY);
const { data, error } = await notix.emails.send({
to: "amara@example.com",
templateId: "YOUR_NOTIX_TEMPLATE_ID",
variables: {
firstName: "Amara",
trackingCode: "KD-4471",
},
});
Notix: host smtp.usenotix.dev, ports 465 (TLS) or 587 (STARTTLS), username notix, and an API key as the password.
Customer.io sends transactional mail through its API, so there is usually no SMTP setting to change. If another app of yours sends over SMTP, point it at Notix with the settings on the right.
Every Notix webhook is signed with X-Notix-Signature and retried up to six times. Point a new endpoint at Notix and match the names below.
| Customer.io | Notix | Good to know |
|---|---|---|
email sent | email.sent | |
email delivered | email.delivered | |
email opened | email.opened | |
email clicked | email.clicked | |
email bounced | email.bounced | |
email spammed | email.complained | |
email dropped | email.suppressed | |
email failed | email.failed | |
email unsubscribed | contact.unsubscribed |
The importer enforces the order. Someone who opted out at Customer.io cannot get mail from Notix.
Give each app the key it needs: full access, or sending only.
Every delivery carries an HMAC signature and a timestamp, so your handler can refuse anything forged or replayed.
API request logs are kept 30 days. Keys, codes, email bodies and attachments are hidden before a log is saved.
If bounces or complaints climb past safe levels, the domain pauses before it damages your reputation. How it works.
The first broadcast to imported contacts is reviewed by us before it goes out.
Send an Idempotency-Key header, up to 256 characters, with any send or batch. Notix keeps the result for 24 hours: a retry with the same key and body gets the first answer back, marked Idempotent-Replayed: true, and the same key with a different body is refused with a 409.
In notix-js it is one option: emails.send(payload, { idempotencyKey }). See it in action.
Send sign-in codes by SMS or email, with a risk check first, and verify them in one call. One-time codes.
Claude, ChatGPT or Cursor can work with Notix, and live keys ask you first above a limit you set. Connect your AI.
Top up a wallet in naira, shillings or dollars, and Pro renews from it. Pricing.
Receive mail on your own domain and forward it on, with an optional forwarded-message header. Inbound email.
Campaigns to a list, segment or topic, and email sequences that run themselves, behind the same key.
A domain may only have one SPF record, so you add Notix to the line you already have rather than replacing it. Add include:_spf.usenotix.dev beside the include Customer.io gave you, and remove theirs once you have switched off.
We haven't recorded Customer.io's list prices for the plan this page is about, so there is no comparison here rather than a figure for a different product of theirs. Notix pricing is on one page, and a migration call can work your own numbers through with you.
Convert your code, bring your audience across with unsubscribes first, and move your volume over four weeks. We are happy to do it with you.