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.

Read the docs

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

One key, one SDK, one log for all of them.

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.

Pricing