← All @molecule/* packages · App templates

@molecule/api-sms-twilio

Provider bond · sms · API (Node) · v1.0.1 · Apache-2.0

Twilio SMS provider for molecule.dev

npm install @molecule/api-sms-twilio

npm · Source on GitHub · Implements @molecule/api-sms

How it works

@molecule/api-sms-twilio is a provider bond on the API (Node) side: it implements the sms core interface (@molecule/api-sms) with a concrete vendor or library behind it.

Your code calls the core; you wire this provider once at startup. Swapping vendors later is one line in that wiring, not a rewrite.

import { setProvider } from '@molecule/api-sms'
import { createProvider } from '@molecule/api-sms-twilio'

// Bond at startup (reads TWILIO_* env vars by default)
setProvider(createProvider())

// Or with explicit config
setProvider(
  createProvider({
    accountSid: 'AC...',
    authToken: 'xxx',
    defaultFrom: '+15551234567',
  }),
)

Works with: @molecule/api-logger, @molecule/api-secrets, @molecule/api-sms

Secrets: TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN, TWILIO_FROM_NUMBER

Reference

Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit src/index.ts JSDoc, not this file.

Twilio SMS provider for molecule.dev.

Implements the @molecule/api-sms interface using the Twilio REST API.

options.scheduledAt is forwarded as Twilio's sendAt + scheduleType: 'fixed', which Twilio only honors for messages sent through a Messaging Service — with a plain from phone number (this bond's only sender mode) the API rejects the scheduled send. Treat scheduledAt as unsupported here and delay dispatch with a job scheduler instead.

Credentials are captured ONCE when createProvider() runs — setting TWILIO_* later in the same process has no effect until the provider is re-created (an API restart after filling in secrets does this).

Quick Start

import { setProvider } from '@molecule/api-sms'
import { createProvider } from '@molecule/api-sms-twilio'

// Bond at startup (reads TWILIO_* env vars by default)
setProvider(createProvider())

// Or with explicit config
setProvider(
  createProvider({
    accountSid: 'AC...',
    authToken: 'xxx',
    defaultFrom: '+15551234567',
  }),
)

Type

provider

Installation

npm install @molecule/api-sms-twilio @molecule/api-logger @molecule/api-secrets @molecule/api-sms twilio

API

Interfaces

TwilioSMSConfig

Configuration for the Twilio SMS provider.

interface TwilioSMSConfig {
  /** Twilio Account SID. Defaults to `process.env.TWILIO_ACCOUNT_SID`. */
  accountSid?: string

  /** Twilio Auth Token. Defaults to `process.env.TWILIO_AUTH_TOKEN`. */
  authToken?: string

  /** Default sender phone number in E.164 format. Defaults to `process.env.TWILIO_FROM_NUMBER`. */
  defaultFrom?: string
}

Functions

createProvider(config)

Creates a Twilio-backed {@link SMSProvider}.

Credential validation is DEFERRED to first use (send/sendBulk/getStatus) rather than thrown here — matching the slack/web-push bonds in this category. An app that has selected Twilio but hasn't filled in its secrets yet can still boot; only the first actual SMS attempt throws the actionable "accountSid/authToken is required" error, instead of the whole API crashing at setProvider(createProvider()) startup time.

function createProvider(config?: TwilioSMSConfig): SMSProvider
  • config — Twilio provider configuration. Falls back to environment variables when individual fields are omitted.

Returns: A fully initialised SMSProvider backed by Twilio.

Constants

smsTwilioSecretDefinitions

Secret definitions required by the Twilio SMS bond.

const smsTwilioSecretDefinitions: SecretDefinition[]

Core Interface

Implements @molecule/api-sms interface.

Injection Notes

Requirements

Peer dependencies:

  • @molecule/api-logger ^1.0.1
  • @molecule/api-secrets ^1.0.1
  • @molecule/api-sms ^1.0.1

Environment Variables

Runtime Dependencies

  • @molecule/api-logger
  • @molecule/api-secrets
  • @molecule/api-sms
  • twilio

createProvider() does NOT validate credentials eagerly — missing TWILIO_ACCOUNT_SID/TWILIO_AUTH_TOKEN will not throw at bond time. setProvider(createProvider()) always succeeds; the actionable "accountSid/authToken is required" error is thrown on the first actual send()/sendBulk()/getStatus() call instead, so a scaffolded app that selected Twilio before filling in secrets still boots (SMS just degrades until the secret is set), matching the slack/web-push bonds in this category.

E2E Tests

Integration checklist — drive the real UI (live preview, no mocks), adapt each item to this app's actual screens/flows, and check every box off one by one. A box you can't check is an integration bug to fix — not a skip:

  • Each SMS-triggering flow (phone verification, OTP login, alerts the app defines) confirms the send in the UI and a message actually reaches the transport. The sandbox CAPTURES outbound SMS instead of sending — read it with the read_activity tool (filter type 'sms'); the code/link is in its payload. Never mock the flow or modify production code to expose it.
  • The OTP round-trip completes: request a code → read the captured message's code → enter it in the UI → the flow advances; a wrong or expired code is rejected with a visible error.
  • Messages go only to the authenticated user's own verified number — no UI or endpoint lets a caller text an arbitrary number (spam/abuse vector).