A single line has a ceiling (see Limits). The way to
scale beyond it is to add more lines and spread your users across them.
When to add a line
Add a second (or third, or tenth) line when:
- Sustained traffic on an existing line is approaching the per-line numbers.
- A single-line outage would be unacceptable — you want a line that can take
over if one gets flagged or its underlying Apple ID needs to re-auth.
- You’re running multiple distinct products or brands and want clean
separation between them.
Spread users across lines
Each user should be assigned to one line, and the assignment should be
stable: the same user always lands on the same line so their
conversation history stays continuous.
How you assign users is up to you. The send API requires you to specify
from on every call, so the routing decision lives in your code:
import { createClient } from "@messages-dev/sdk";
const client = createClient();
// Pick a line for this user. Whatever logic you use, keep it stable
// so the same user always ends up on the same line.
const line = pickLineForUser(userId);
await client.sendMessage({
from: line,
to: userPhone,
text: "Hey!",
});
A few practical notes:
- Keep traffic balanced. If one line carries 80% of users, you’ve still
only got the throughput of that one line.
- Monitor each line independently. The outbound:inbound ratio, daily
volume, and unanswered-message counts from Limits
apply per line, not aggregated across your account.
- Treat new lines as new lines. A line that’s been in use for 6 months
isn’t comparable to one provisioned yesterday. Ramp new ones up gradually.
You can scope an API key to specific lines using the lineIds field when
creating the key. This is useful if different parts of your stack should
only be able to send from a subset of lines.
A contact card can carry more than one phone number. If you deliver a
vCard with both your primary line and a backup line, the user saves
both to their contacts. If your primary line is ever throttled,
unreachable, or being warmed back up, the user already has the backup
saved and can text it directly:
await client.sendContactCard({
from: "+15550000001",
to: userPhone,
firstName: "Acme",
lastName: "Support",
phones: [
{ type: "cell", value: "+15550000001" }, // primary
{ type: "main", value: "+15550000002" }, // backup
],
});
Send this once during onboarding (or any other moment where it’s natural
for the user to save your contact). From then on, both numbers live in
their address book and they can fall back to the backup if your primary
line goes quiet.
See Contact cards for the full vCard reference.