SMS Best Practices

Data & APIs

Provides SMS compliance, formatting, and delivery best practices for the Sendly API. Covers TCPA compliance, quiet hours, opt-out handling, E.164 phone formatting, message segmentation, and carrier verification. Applies when building SMS features that must be compliant and deliverable.

Install

openclaw skills install sms-best-practices

SMS Best Practices

Phone number formatting

Always use E.164 format: +{country_code}{number} with no spaces, dashes, or parentheses.

InputE.164Valid?
(415) 555-1234+14155551234After formatting
415-555-1234+14155551234After formatting
+14155551234+14155551234Yes
4155551234+14155551234Need 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_out error
  • An opt_out.created webhook 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:

EncodingSingle segmentMulti-segment per part
GSM-7 (ASCII)160 chars153 chars
UCS-2 (emoji/Unicode)70 chars67 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

ErrorCauseFix
invalid_phone_numberNot E.164 formatFormat as +{country}{number}
insufficient_creditsBalance too lowPurchase credits at sendly.live
quiet_hours_violationMarketing during 9pm–8amUse transactional type or wait
opted_outRecipient unsubscribedDo not retry — respect opt-out
content_violationSHAFT filter triggeredRevise message content
not_verifiedNumber not carrier-verifiedComplete verification at sendly.live

Full reference