Back to KB
Difficulty
Intermediate
Read Time
8 min

SMS Delivery Receipts on AWS Lambda

By Codcompass Team··8 min read

Serverless SMS Delivery Verification: Webhook Patterns for Sinch and Lambda

Current Situation Analysis

In serverless communication architectures, a common anti-pattern is treating the HTTP 200 OK response from an SMS provider as proof of delivery. When you invoke a messages:send endpoint, the provider acknowledges receipt of your request, not the recipient's device. This creates a "black box" scenario where critical notifications—MFA codes, password resets, fraud alerts—may silently fail due to carrier filtering, disconnected numbers, or network outages.

This gap is frequently overlooked because initial development focuses on the happy path. However, in production, the inability to verify delivery leads to:

  • Operational Blindness: Support teams cannot distinguish between "user didn't receive" and "user ignored."
  • Compliance Risks: Financial and healthcare sectors often require audit trails proving a message reached the intended party.
  • Inefficient Retries: Without status feedback, systems cannot automatically retry failed messages or fall back to alternative channels like email.

Data from the Sinch Conversation API indicates that a single outbound message generates multiple state transitions. Relying solely on the send acknowledgment ignores the DELIVERED, FAILED, and READ states that occur asynchronously. Implementing a webhook-based receipt system transforms SMS from a fire-and-forget mechanism into a verifiable communication channel.

WOW Moment: Key Findings

The shift from send-only to receipt-driven architectures introduces measurable improvements in reliability and operational control. The following comparison highlights the impact of implementing delivery receipts.

StrategyDelivery VisibilityFailure RecoveryCompliance AuditInvocation Overhead
Send-OnlyNoneManual investigation requiredNo proof of receiptLow (1 invocation per message)
Receipt-DrivenFull state trackingAutomated retry/fallbackYes (status logs)Moderate (2–3 invocations per message)

Why this matters: The invocation overhead increases by 200–300% because Sinch emits callbacks for QUEUED_ON_CHANNEL, DELIVERED, or FAILED. However, this cost is negligible compared to the business impact of undelivered transactional messages. The receipt-driven approach enables idempotent state updates, automated alerting on failure codes, and precise correlation of messages to business entities.

Core Solution

The architecture leverages AWS Lambda Function URLs for direct HTTPS ingress, eliminating the need for API Gateway overhead. The solution prioritizes security via HMAC validation and reliability via asynchronous processing.

Architecture Decisions

  1. Lambda Function URL: Provides a native HTTPS endpoint for the webhook. This reduces latency and cost compared to API Gateway while maintaining serverless scalability.
  2. HMAC-SHA256 Validation: Sinch signs every webhook payload. The Lambda must verify the signature to prevent spoofing. The signature covers the body, a nonce, and a timestamp to prevent replay attacks.
  3. SQS Decoupling: Webhook handlers must return 200 OK rapidly. Sinch expects low latency and retries on 5xx or 429 responses. Heavy processing (database writes, external API calls) should be offloaded to an Amazon SQS queue to ensure the callback is acknowledged immediately.
  4. SSM Parameter Store: The webhook secret is stored as a SecureString in AWS Systems Manager Parameter Store. The Lambda caches the secret in the execution environment to minimize SSM API calls.

Implementation

The following TypeScript implementation demonst

🎉 Mid-Year Sale — Unlock Full Article

Base plan from just $4.99/mo or $49/yr

Sign in to read the full article and unlock all 635+ tutorials.

Sign In / Register — Start Free Trial

7-day free trial · Cancel anytime · 30-day money-back