Communication

Twilio SMS

Send transactional SMS to clients (payment receipts, day-of texts).

What you get

Send transactional SMS to clients from your Twilio number. RemixCRM uses Twilio's REST API directly — no client SDK, no extra dependencies.

Out of the box, Twilio fires for:

  • Payment receipts — when you record a payment on an event, the client's primary phone gets a confirmation: Thanks, [name]! We received your $250.00 deposit for your event on 2026-08-15. — [your business]

Future versions will add reminders, day-of texts, and contract-sent notifications. The integration is org-scoped, so each org uses its own Twilio account/number.

Prerequisites

  • A Twilio account at console.twilio.com
  • A Twilio-owned phone number with SMS enabled (~$1/mo)
  • A verified Caller ID if you're on a trial account (trial accounts can only text to verified numbers)

Setup

1. Buy or use an existing number

In the Twilio Console:

  1. Develop → Phone Numbers → Manage → Active numbers
  2. If you don't have one: Buy a number → enable SMS capability
  3. Note the number in E.164 format (e.g. +15551234567)

2. Grab account credentials

On the Twilio Console home:

  • Account SID — starts with AC…, ~34 chars
  • Auth Token — click "View" to reveal

Security: Auth tokens grant full account access. Use a Twilio API Key in production if you want narrower permissions. RemixCRM accepts either — paste the API key SID as Account SID and the secret as Auth Token.

3. Configure in RemixCRM

  1. Settings → Integrations → Twilio SMS
  2. Check Enable Twilio SMS
  3. Paste Account SID, Auth Token, From Number (E.164 format)
  4. Save

4. Test

The easiest test: record a small payment on a test event whose client has a phone on file. The client should receive the receipt SMS within a few seconds.

Or test directly with curl using your credentials:

curl -X POST "https://api.twilio.com/2010-04-01/Accounts/$SID/Messages.json" \
  -u "$SID:$TOKEN" \
  --data-urlencode "To=+1YOURNUMBER" \
  --data-urlencode "From=+15551234567" \
  --data-urlencode "Body=Test from RemixCRM"

How RemixCRM uses Twilio

Event When What's sent
Payment recorded on event Admin adds a payment Receipt SMS to client's primary phone

All sends are best-effort — if Twilio isn't configured, or the client has no phone on file, or the send fails, the original action (recording the payment) still succeeds. The SMS failure is logged but doesn't surface to the user.

To find the client phone, RemixCRM uses the primary phone from client_phones (falls back to the first phone if none is marked primary).

Costs

  • Number rental: ~$1/mo
  • Outgoing SMS: ~$0.0083 per segment (US/Canada), more for international
  • Inbound SMS: ~$0.0075 per segment (only matters if you wire inbound webhooks)

A "segment" is 160 ASCII or 70 Unicode characters. Long messages split into multiple segments.

Programmatic SMS

lib/sms/twilio.ts exposes a single function:

import { sendSms } from '@/lib/sms/twilio'

const result = await sendSms(orgId, '+15551234567', 'Your event is tomorrow!')
// → { ok: true, sid: 'SM…' } or { ok: false, error: '…', disabled?: true }

Use this from any server action or cron job. It silently returns { ok: false, disabled: true } if Twilio isn't configured for the org — no need to gate calls.

Troubleshooting

"Twilio not configured"

Settings → Integrations → Twilio SMS — make sure the Enable checkbox is checked AND all three fields are filled.

HTTP 21211: Invalid 'To' Phone Number

The recipient phone isn't in E.164 format. RemixCRM passes through whatever is stored on the client record. Edit the client's phone to include +1 (or the appropriate country code).

HTTP 21608: Trial account can only send to verified numbers

You're on a Twilio trial. Either verify the recipient in Twilio Console → Phone Numbers → Verified Caller IDs, or upgrade your Twilio account (adding $20 of credit is enough to remove the restriction).

HTTP 30005: Message not delivered

The recipient's carrier rejected the message. Common causes:

  • Number is a landline
  • Number is on a do-not-call/STOP list
  • Twilio's anti-spam systems flagged the content (avoid all-caps and link shorteners)