Bird

Migrate SMS from Amazon SNS to Bird

Replace the SMS delivery part of an SNS application while keeping the AWS services that already run it. This guide covers direct phone-number publications and SMS subscribers on standard topics. Your Lambda functions, SQS queues and non-SMS subscriptions can stay in place.

1. Separate SMS from topic distribution

Inventory direct Publish calls with PhoneNumber and publications with TopicArn. For each topic, record the SMS recipients, subscription filters and other subscribers. A Bird SMS request addresses one recipient; it does not recreate an SNS topic or its filtering rules.
If SNS already feeds a Lambda function or queue worker, keep that consumer and replace its SMS send call. When replacing SMS subscriptions on a topic, first define how the worker obtains the permitted recipients and applies the existing filters. Prevent both the old SMS subscription and the new worker from sending the same notification during cutover. The SNS publishing guide describes the two source paths.
Keep the AWS region and IAM identity with the existing AWS client. Bird requests use a workspace API key and a regional API host; the SDK selects that host from the key. An IAM role or SNS topic ARN cannot authenticate a Bird send.

2. Retain audience preferences

Reconcile your application preferences with the account's SNS opt-out records. SNS opt-out can prevent delivery even while the phone number remains subscribed to a topic. Topic membership alone therefore does not establish permission to send.
The AWS CLI can read the account's list without changing recipients:
Code example
aws sns list-phone-numbers-opted-out --output json
Use the relevant AWS profile and region, retain pagination when calling the API directly, and reconcile the result with requests received through your own support or preference settings. Do not call an opt-in operation merely to enable migration.
Import reviewed preferences using the Bird suppression workflow. Bird's SMS suppression is scoped to a sender and subscriber. Preserve an account-wide refusal across the senders it covered and keep broader application preferences authoritative. Map the intended purpose of each audience separately from its transport subscription.

3. Configure Bird sending

Follow sender setup to choose an eligible sender, complete the destination's registration requirements and enable the country. An SNS sender ID or an AWS origination number does not automatically become a sender held by the Bird workspace. Coordinate number transfer separately if the number must remain the same.
SNS request or resultBird implementation
Direct phone sendOne to per send, in E.164 format.
Messagetext, with an explicit from and category.
Message typeClassify the content's purpose. Transactional is not a substitute for deciding whether a message is authentication, service or transactional.
Sender IDConfigure and select an eligible Bird sender; carry over any country-specific registrations through their supported process.
Publication IDStore Bird's returned id alongside the application event ID and recipient.
Topic fan-outResolve recipients and routing in the existing application; use independent sends or an API batch.
SNS uses PhoneNumber for a direct send, AWS.SNS.SMS.SMSType for the message type and AWS.SNS.SMS.SenderID for the sender ID. Preserve its returned MessageId with the historical attempt.
For a first send, compare these commands. Configure your AWS profile for the source example. For Bird, install the CLI, set BIRD_API_KEY, and set BIRD_SMS_FROM to a configured sender. SMS_TO must be a permitted test recipient. Retain MESSAGE_KEY with that logical message. Each send command sends a message when executed.
Code example
aws sns publish \
  --phone-number "$SMS_TO" \
  --message "Your studio visit is tomorrow at 14:00." \
  --message-attributes '{"AWS.SNS.SMS.SMSType":{
    "DataType":"String","StringValue":"Transactional"
  }}'
Code example
bird sms send \
  --from "$BIRD_SMS_FROM" \
  --to "$SMS_TO" \
  --text "Your studio visit is tomorrow at 14:00." \
  --category transactional \
  --idempotency-key "$MESSAGE_KEY"
A returned message ID records acceptance. Follow the delivery events to learn what happened afterward. Use the Node.js quickstart or Python quickstart to put this send into your worker. Review encoding and segments using Sending SMS.

4. Replace the SMS worker

Persist an application notification ID, recipient, selected provider, send body, retry key and provider message ID. One source event can produce several intended messages; each recipient's message needs its own identity. A duplicate source event must find the existing attempt before it creates more work.
Use the same body and Bird idempotency key when retrying an uncertain request within the replay window. After that window, inspect the recorded message and unresolved attempt before sending again. Changing providers after a timeout can duplicate a message already accepted by SNS. SNS FIFO deduplication settings do not add idempotency to a direct phone-number publish.
Retain the worker's queue retry and dead-letter handling. A successful SNS publication into that queue establishes that the source event was accepted; it does not establish that the subsequent SMS was delivered. Persist a permanent send refusal for review instead of retrying the same invalid sender indefinitely.

5. Verify delivery and rollback

SNS can publish SMS delivery logs to CloudWatch. Check the configured success sampling rate before using those logs as a comparison baseline: absent successful records can reflect sampling. Retain the provider response and the meaning of the logged outcome. AWS's delivery-monitoring guide documents those observations.
On Bird, install the persistent delivery-receipt handler, verify its signatures and correlate data.sms_id to the stored attempt. Track accepted, delivered, failed and unresolved messages separately. For replies on a supported number, add the two-way reply worker; a delivery log is not an incoming-message consumer.
Before increasing traffic, exercise a duplicated source event, a lost send response, an opted-out recipient and a repeated receipt. Reconcile the same recipient cohort, encoding and reporting period across providers. A rollback changes where new messages go; keep both receipt consumers available for earlier sends and reconcile unfinished attempts before rerouting them.

References and next steps

Start now to configure Bird SMS, or talk to sales about sender transfers and a larger migration.

Related resources

Continue with the documentation, guides and examples for this topic. Resources are in English.