# Customers

Source: https://joinsimplesms.com/docs/customers
Index: https://joinsimplesms.com/llms.txt

For platforms (SaaS, agent builders, agencies) that send on behalf of other
businesses. A customer is a label you control: assign numbers to it, and
every message, verification, event and webhook from those numbers carries its
`customer_id`, with usage you can read back per customer to rebill.

Entirely optional. Accounts that never create a customer see no change.

## Create a customer

`POST /v1/customers`

```bash
curl -X POST https://api.joinsimplesms.com/v1/customers \
  -H "Authorization: Bearer ssms_sk_test_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Acme Dental", "external_id": "acct_42", "metadata": { "plan": "pro" } }'
```

```json
{
  "id": "cus_a1B2c3D4e5F6g7",
  "object": "customer",
  "name": "Acme Dental",
  "external_id": "acct_42",
  "metadata": { "plan": "pro" },
  "created_at": "2026-10-01T12:00:00.000Z",
  "updated_at": "2026-10-01T12:00:00.000Z"
}
```

| Parameter | Type | Notes |
| --- | --- | --- |
| `name` | string | Optional, up to 200 characters. |
| `external_id` | string | Optional. Your id for them; unique per account (`409` if taken). |
| `metadata` | object | Optional. Up to 50 string values. Keys up to 40 characters, no `. # $ / [ ]`. |

## Retrieve, update, delete, list

- `GET /v1/customers/{id}` also returns `phone_numbers` assigned to it.
- `PATCH /v1/customers/{id}` changes only the fields you send;
  `metadata` replaces the whole object, `null` clears a field.
- `DELETE /v1/customers/{id}` deletes it and unassigns its numbers (they
  stay on your account). Messages, events and usage already attributed keep
  the id: they record what happened.
- `GET /v1/customers?limit=25&cursor=...` lists newest first;
  `?external_id=acct_42` finds one by your id.

## Attribute traffic

- **Numbers**: `POST /v1/numbers` with `customer_id`, or
  `PATCH /v1/numbers/{number}` with `{ "customer_id": "cus_..." }`.
- **Outbound messages** inherit the customer of their `from` number, or take
  an explicit `customer_id`. A number assigned to one customer can't send
  as another (`400`); unassigned numbers can send for anyone.
- **Inbound messages** (and STOP/HELP replies) inherit the customer of the
  number they arrived on.
- **Verifications** take an optional `customer_id` on `POST /v1/verify`.
- **Events and webhooks** about any of the above carry `data.customer_id`.
- `GET /v1/messages?customer_id=cus_...` lists one customer's messages.

## Usage

`GET /v1/customers/{id}/usage?start=2026-10-01&end=2026-10-31`

```json
{
  "object": "customer_usage",
  "customer_id": "cus_a1B2c3D4e5F6g7",
  "mode": "live",
  "start": "2026-10-01",
  "end": "2026-10-31",
  "messages_sent": 1204,
  "messages_failed": 3,
  "messages_received": 377,
  "verifications_sent": 88,
  "verifications_approved": 81,
  "numbers": 2,
  "phone_numbers": ["+14155550132", "+14155550133"],
  "daily": [{ "date": "2026-10-01", "messages_sent": 40, "...": 0 }]
}
```

UTC days, inclusive, up to 366 days; the default is this month to date.
Usage follows the key you call with: a test key reports sandbox traffic and a
live key live traffic, so test runs never show up in what you rebill.
`numbers` is the count assigned right now.

## With the SDKs

```js
const acme = await sms.customers.create({ name: 'Acme Dental', externalId: 'acct_42' });
await sms.numbers.update('+14155550132', { customerId: acme.id });
await sms.messages.list({ customerId: acme.id });
await sms.customers.usage(acme.id, { start: '2026-10-01', end: '2026-10-31' });
```

```python
acme = client.customers.create(name="Acme Dental", external_id="acct_42")
client.numbers.update("+14155550132", customer_id=acme["id"])
client.messages.list(customer_id=acme["id"])
client.customers.usage(acme["id"], start="2026-10-01", end="2026-10-31")
```

## Responsibility

A customer label is bookkeeping for you. It does not register the business
with carriers, make it our customer, or change who is responsible for its
traffic: you are, as if it were your own ([Terms §2.4](/terms),
[Messaging Policy §7](/messaging-policy)). Each end business still needs its
own brand and campaign registration.
