# SMS (https://coss.com/products/sms)

> coss.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.

## How it works

Send from a registered number, follow the message through its events, and read the replies. One API key covers SMS, email and everything else.

```ts twoslash
import { Coss, verifyWebhook } from "coss";
const coss = new Coss();
declare const request: Request;
declare const secret: string;
// ---cut---
// 1. Send from one of your organization's numbers.
const { data: sms, error } = await coss.sms.send(
  {
    from: "+14155550123",
    to: "+14155550199",
    body: "Your Acme order #1042 has shipped.",
  },
  { idempotencyKey: "order-1042-shipped" },
);
if (sms) console.log(sms.status, sms.segments, sms.encoding); // "queued", 1, "gsm7"

// 2. Follow delivery and replies through webhooks.
const event = await verifyWebhook(await request.text(), request.headers, secret);
if (event.type === "sms.received" && event.data.received_sms_id) {
  const { data: reply } = await coss.sms.received.get(event.data.received_sms_id);
  console.log(reply?.from, reply?.body);
}
```

Sends return `202` with `status: "queued"`, and a background worker hands the message to the carrier. Retrying with the same idempotency key returns the first message instead of sending a second one. See [sending SMS](/docs/sms/sending) and the [API reference](/docs/api-reference/sms/send-sms).

## Carrier-ready from day one

The parts of SMS that usually take a week of paperwork and a second vendor are part of the API.

### Numbers bought for you
Owners and admins buy local or toll-free numbers on the dashboard's organization **SMS** page. Numbers belong to the organization, so every environment's keys send from them, and `coss.sms.numbers.list()` says which can send now. See [numbers and registration](/docs/sms/senders).

### 10DLC and toll-free registration
One form becomes the business profile, the brand and the campaign US carriers require, each submitted once the previous review passes. Toll-free numbers get toll-free verification. The dashboard shows each status, and why a step was rejected.

### Opt-outs honored everywhere
A reply of STOP, UNSUBSCRIBE, CANCEL, END or QUIT suppresses the number in every live environment of the organization, and START lifts it. Each change sends an `sms.opted_out` or `sms.opted_in` webhook. See [receiving](/docs/sms/receiving#stop-start-and-help).

### Segments counted up front
Every message says how it was counted: `gsm7` or `ucs2`, and how many segments. Extended characters and emoji are never split across segments, and coss.com counts exactly as the carrier does, so the bill matches what you saw.

### Scheduled sends
Pass `scheduled_at` up to 30 days ahead and cancel it any time before. The sender, the country and the suppression list are checked again at send time, so a number that opted out in the meantime is never texted.

### Events, webhooks and logs
`sms.sent`, `sms.delivered`, `sms.undelivered`, `sms.failed` and `sms.received` reach your [webhooks](/docs/webhooks), signed and retried, and every event is a line in your environment's [logs](/docs/logs). Payloads never carry the text.

## Built to keep your numbers deliverable

Carriers filter senders that text people who didn't ask. coss.com watches the same signals they do.

Each environment keeps its own SMS suppression list. A send to a suppressed number fails at once with `suppressed` and is never handed to a carrier or billed. Numbers that can't receive SMS and carrier-refused opt-outs are added automatically, and you can add your own with `coss.sms.suppressions.add()`.

A sample of live messages is [screened](/docs/sms/sending#content-screening) for spam, phishing, malware and fraud before it is sent, like email. coss.com also measures each organization's opt-out rate and carrier filtering rate over a rolling window: high rates bring a warning, then a suspension of live sending, before carriers start blocking your numbers. Live keys can text the same number at most 10 times an hour, which stops a looping form or a pumping attack there.

## Specifications

The limits a send is checked against. The docs list each one in context.

- Number format: E.164, +14155550199
- GSM-7 segment: 160 characters, 153 when split
- UCS-2 segment: 70 characters, 67 when split
- Longest message: 10 segments
- Scheduling window: up to 30 days ahead
- Messages to one number: 10 an hour per organization, live
- Number kinds: local (10DLC) and toll-free, US and CA
- Default countries: US and Canada
- Opt-out rate: warning at 2%, suspension at 5%
- Carrier filtering rate: warning at 3%, suspension at 10%
- Messages kept: 45 days
- Sandbox sends: 200 segments a day per environment

## Test every outcome in a sandbox

Sandbox keys simulate carriers, so the whole flow works before you own a number.

Sandbox (`coss_test_…`) keys accept any `from` number and skip the number, country and plan checks. Send to `+15005550006` and the message is delivered, to `+15005550004` and the carrier filters it, to `+15005550009` and the recipient has opted out, to `+15005550008` and a reply arrives in the same environment. Statuses, events, webhooks and logs behave as in live environments, and nothing is sent or billed. See [testing SMS](/docs/sms/testing).

## Pricing

Live messages are billed per segment by destination country, once a carrier has them, carrier fees included. Numbers and US carrier registration fees are passed through at cost.

| Product | Rate | |
| --- | --- | --- |
| SMS (US) | $0.0142 per segment | |
| SMS (other countries) | $0.0208 to $0.1134 per segment | By country: coss.com/pricing#sms |
| SMS received (US) | $0.0148 per segment | |
| SMS phone numbers (local) | $1.15 per number-month | |
| SMS phone numbers (toll-free) | $2.15 per number-month | |
| SMS registration fees (brand registration) | $4.50 | Passed through at cost |
| SMS registration fees (brand vetting) | $41.50 | Passed through at cost |
| SMS registration fees (campaign vetting) | $15.00 | Passed through at cost |
| SMS registration fees (campaign, monthly) | $10.00 | Passed through at cost |
| SMS registration fees (low-volume campaign, monthly) | $1.50 | Passed through at cost |

Live SMS needs a paid plan; Free organizations send in sandbox environments. Failed, suppressed and canceled messages cost nothing. Every country's rate per segment, sent and received, is on the [pricing page](/pricing#sms).

## Frequently asked questions

### How do I send an SMS with coss.com?

Call coss.sms.send() with a from number, a to number in E.164 form and a body. The API returns 202 with the message queued, a background worker hands it to the carrier, and sms.* webhooks report what the carrier did with it.

### Does coss.com handle US A2P 10DLC registration?

Yes. Owners and admins fill in one form on the dashboard, and coss.com submits the business profile, the brand and the campaign to the carriers in order, waiting for each review before the next step. Toll-free numbers go through toll-free verification instead. Reviews usually take a few days.

### Do I need my own Twilio account?

No. coss.com sends through Twilio on its own account, with a subaccount per organization, and buys the numbers and submits the registrations for you. Numbers and US carrier registration fees appear on your coss.com invoice.

### What happens when someone replies STOP?

The number is suppressed in every live environment of your organization, since your numbers are shared by all of them, and each affected environment gets an sms.opted_out webhook. A reply of START removes the opt-out. The confirmation carriers require is sent automatically.

### How are SMS messages counted and billed?

A message is split into segments of 160 GSM-7 characters, or 70 when it contains any other character such as an emoji, and longer messages take 153 or 67 per segment. A live message is billed per segment at its destination country's rate once it reaches a carrier; failed, suppressed and canceled messages cost nothing. The pricing page lists every country.

### Can I test SMS without a phone number?

Yes. Sandbox keys accept any from number and simulate carriers, with simulator numbers for delivered, invalid, filtered, opted-out and replied messages. Nothing is sent or billed, and the statuses, events, webhooks and logs work as in live environments.

### Which countries can I send SMS to?

Every organization starts with the United States and Canada. Owners and admins can allow other priced countries on the dashboard; a few countries where SMS pumping fraud is common need support to unlock them first. Toll-free numbers only send to the US and Canada.
