Product notifications across email and SMS.
coss.com sends product notifications by email and SMS on one API key, with templates, scheduled sends, signed delivery webhooks and one log across both.
The problem
Notifications go out on several channels, and each channel usually means another provider, another key and another log.
Order confirmations, password resets, shipping updates and reminders go out by email and, increasingly, by SMS. With one provider per channel, each has its own API key, its own webhook format, its own suppression list and its own dashboard, and answering "did the customer get it?" means checking several places.
coss.com sends email and SMS through one SDK and one API key. Both report delivery through the same signed webhooks and the same log, both honor unsubscribes and opt-outs, and apps that only speak SMTP send through the SMTP relay.
How it works
Send by email and SMS with one client, then follow both through the same webhook endpoint.
// An email from a published template, with its variables.
await ..(
{
: "Acme <orders@acme.com>",
: "ada@example.com",
: "order-shipped",
: { : "Ada", : "https://acme.com/t/1042" },
},
{ : "order-1042-shipped" },
);
// An SMS reminder tomorrow morning, from the same client.
await ..({
: "+14155550123",
: "+14155550199",
: "Acme: your order 1042 arrives today.",
: "2026-11-11T09:00:00Z",
});
// One webhook endpoint for both channels.
const = await (await .(), ., );
if (. === "email.delivered") await (..);
if (. === "sms.delivered") await (..);Read more in sending email, templates, sending SMS and webhooks.
What you get
Two channels on one platform, with the delivery record in one place.
Email and SMS on one key
coss.email.send() and coss.sms.send() share the API key, SDK, webhook endpoints, logs and sandbox environments. Sends return 202 at once and a background worker hands them to the provider or carrier.
Templates
Templates keep subjects and bodies in coss.com, versioned and localized, with typed variables. Every email records which template, version and locale it was rendered from.
Scheduled sends
Pass scheduled_at up to 30 days ahead. Scheduled emails can be rescheduled or canceled, and the sender and suppression list are checked again when the time comes.
Signed delivery webhooks
email.delivered, email.bounced, sms.delivered, sms.undelivered and the rest arrive signed with each endpoint's own secret, retried 7 times over about 28 hours.
One log across products
Every API request, email and SMS event and webhook attempt of an environment is in one log, searchable in the dashboard, readable with coss.logs.list() and streamable to your own tools through log drains.
Opt-outs honored
Bounces, complaints and one-click unsubscribes add suppressions that later sends skip. An SMS reply of STOP suppresses the sender in every live environment.
Specifications
The limits of each channel. The docs list each one in context.
- Scheduling window
- up to 30 days ahead, email and SMS
- Emails per batch request
- 100
- Custom headers per email
- 15
- Tags per email
- 50
- Idempotency window
- 24 hours
- Webhook retries
- 7 over about 28 hours
- Log query range
- up to 31 days
- SMTP ports
- 465 (TLS), 587 (STARTTLS)
Pricing
Email is billed per recipient and SMS per segment, by country. Sandbox sends are free.
The Free plan includes 3,000 email recipients a month. Live SMS is available on paid plans. See pricing for the plans.
Questions
- Can I send email and SMS with the same API key?
- Yes. coss.email.send() and coss.sms.send() use the same key, SDK, webhook endpoints, logs and sandbox environments. A development key simulates both, and a production key sends both for real.
- How do I schedule a notification?
- Pass scheduled_at, an ISO 8601 timestamp with a time zone offset up to 30 days ahead, to an email or SMS send. Scheduled emails can be rescheduled or canceled until dispatch starts, and the sender and suppression list are checked again at send time.
- How do I know a notification was delivered?
- Subscribe a webhook endpoint to events such as email.delivered, email.bounced, sms.delivered and sms.undelivered. Every webhook is signed with the endpoint's own secret and retried on failure, and every event also appears in the environment's log.
- Does coss.com honor unsubscribes and SMS opt-outs?
- Yes. Permanent bounces, complaints and one-click unsubscribes add suppression entries that later sends skip, and an SMS reply of STOP suppresses the sender in every live environment until they reply START.
- Can I keep notification copy out of my code?
- Yes. Email templates hold the subject, HTML and text in every language you send, with typed variables. You publish a draft as a numbered version and send it by id or alias with the values for its variables.
- Can my app send notifications over SMTP instead of the API?
- Yes. Use smtp.coss.com on port 465 or 587 with the username coss and an API key as the password. Each message gets the same sender checks, suppressions, quotas, webhooks and logs as the API.
The products
- Emailcoss.com Email is a transactional email API. Send single, batch and scheduled email from your domains, with templates, tracking and per-recipient webhooks.
- SMScoss.com SMS is an API that sends and receives text messages from your own phone numbers, with US 10DLC and toll-free registration done for you.
- PlatformThe coss.com platform is what every product shares. Environments and scoped keys, signed webhooks, searchable logs, dated API versions and one bill.
- SMTP relaycoss.com's SMTP relay sends email from anything that speaks SMTP, with an API key as the password and the same checks, tracking and webhooks as the API.
Build it this afternoon.
Hand your coding agent this prompt, then pick the parts you need:
Add coss.com to this project: read https://coss.com/llms.txt, get a development key with `npx coss-cli init --agents`, and build and test with it.