SMS Best Practices
Phone number formatting
Always use E.164 format: +{country_code}{number} with no spaces, dashes, or parentheses.
| Input | E.164 | Valid? |
|---|---|---|
| (415) 555-1234 | +14155551234 | After formatting |
| 415-555-1234 | +14155551234 | After formatting |
| +14155551234 | +14155551234 | Yes |
| 4155551234 | +14155551234 | Need country code |
Message types and compliance
transactional: OTP codes, order confirmations, appointment reminders, account alerts, shipping updates. Allowed 24/7. The recipient has an existing relationship with the sender.
marketing: Promotions, sales, newsletters, product announcements. Subject to:
- Quiet hours: 9pm–8am in the recipient's local timezone
- Prior express written consent required (TCPA)
- Must include opt-out instructions
Misclassifying marketing as transactional violates TCPA and can result in fines up to $1,500 per message.
Opt-out handling
Sendly automatically handles opt-outs. When a recipient replies STOP, UNSUBSCRIBE, CANCEL, END, or QUIT:
- The number is added to the opt-out list
- Future sends to that number return
opted_outerror - An
opt_out.createdwebhook event fires
Do not attempt to send to opted-out numbers. Check message.status for opted_out errors.
Opt-out status is checked automatically when sending — the API returns an opted_out error if the recipient has unsubscribed.
Quiet hours
Marketing messages are blocked during quiet hours (9pm–8am recipient local time). Sendly enforces this automatically — the API returns quiet_hours_violation if you attempt a marketing send during quiet hours.
Transactional messages are exempt from quiet hours.
Message segmentation
SMS messages are limited to 160 characters (GSM-7 encoding) or 70 characters (UCS-2 for emoji/Unicode). Longer messages are split into segments:
| Encoding | Single segment | Multi-segment per part |
|---|---|---|
| GSM-7 (ASCII) | 160 chars | 153 chars |
| UCS-2 (emoji/Unicode) | 70 chars | 67 chars |
Each segment costs credits separately. Keep messages concise.
SHAFT content filtering
Sendly blocks messages containing prohibited content categories (SHAFT):
- Sex/adult content
- Hate speech
- Alcohol
- Firearms
- Tobacco/drugs
Messages flagged by SHAFT filtering return content_violation error.
Credit costs
- US/CA: 2 credits ($0.02) per message segment
- International: varies by destination (see country requirements)
- 1 credit = $0.01
Check balance: GET /api/v1/credits
Carrier verification
To send SMS in the US/CA, your toll-free number must be verified by carriers. This requires:
- Business name and address
- Website URL (use hosted business pages if you don't have one)
- Use case description
- Sample messages
Verification takes 1–5 business days. Use sandbox mode (sk_test_* keys) while waiting.
Common errors
| Error | Cause | Fix |
|---|---|---|
invalid_phone_number |
Not E.164 format | Format as +{country}{number} |
insufficient_credits |
Balance too low | Purchase credits at sendly.live |
quiet_hours_violation |
Marketing during 9pm–8am | Use transactional type or wait |
opted_out |
Recipient unsubscribed | Do not retry — respect opt-out |
content_violation |
SHAFT filter triggered | Revise message content |
not_verified |
Number not carrier-verified | Complete verification at sendly.live |
Full reference
- Compliance docs: https://sendly.live/docs/concepts/compliance
- Quiet hours: https://sendly.live/docs/quiet-hours
- Country requirements: https://sendly.live/docs/country-requirements
- Opt-out handling: https://sendly.live/docs/how-to/handle-opt-outs