Webhooks API
Relevant source files
The following files were used as context for generating this wiki page:
The Webhooks API in Send Again serves as the primary mechanism for receiving asynchronous event notifications from external infrastructure providers. It is specifically designed to handle lifecycle events from email delivery services and billing platforms to ensure the internal state of the application remains synchronized with external actions.
The system currently supports two main integration points: Amazon Simple Notification Service (SNS) for email event tracking (opens, clicks, bounces, etc.) and Polar for credit-based billing and subscription management. These endpoints process incoming HTTP POST requests, verify their authenticity, and update the database accordingly to provide real-time analytics and accurate billing balances.
Sources: README.md:12-15, src/app/api/webhooks/sns/route.ts, src/app/api/webhooks/polar/route.ts
Amazon SNS Webhooks
The SNS webhook endpoint is responsible for processing email deliverability and engagement events. When Amazon SES sends an email, it can be configured to publish events to an SNS topic, which then pushes those notifications to this API.
Event Processing Logic
The endpoint handles several critical event types that impact contact management and campaign analytics:
- Delivery/Send: Confirms successful transmission to the recipient's provider.
- Open/Click: Tracks recipient engagement.
- Bounce/Complaint: Triggers automatic suppression logic to protect sender reputation.
When a Bounce or Complaint event is received, the system automatically marks the contact as unsubscribed and removes them from the active contacts list for that workspace.
Sources: src/app/api/webhooks/sns/route.ts, src/app/api/unsubscribe/route.ts:100-105, README.md:85-89
SNS Integration Flow
The following diagram illustrates how email events flow from AWS into the application:
The diagram shows the transition from external AWS services to internal database updates.
Sources: src/app/api/webhooks/sns/route.ts, README.md:85-89
Polar Billing Webhooks
The Polar webhook endpoint manages the lifecycle of credits and subscriptions. It ensures that when a user purchases a credit pack or updates their plan on Polar, the workspace's billing status and balance are updated immediately.
Supported Event Types
| Event Type | Action Taken |
|---|---|
order.paid | Resolves credit amount from order metadata and applies top-up to workspace. |
subscription.created/updated | Updates workspace_billing with status, period dates, and customer IDs. |
customer.state_changed | Synchronizes the billing status and active plan name (e.g., polar_metered). |
customer.created/updated | Links Polar customer IDs to internal workspace IDs. |
Sources: src/app/api/webhooks/polar/route.ts:130-220, src/lib/db.ts:1005-1050
Credit Resolution Architecture
When an order.paid event arrives, the system must determine how many credits to award. This is done through a multi-step resolution process:
This logic ensures that even if manual configuration changes, the webhook can fallback to product-level mapping to award credits.
Sources: src/app/api/webhooks/polar/route.ts:60-100
Database Synchronization
The Webhooks API interacts heavily with the database layer to persist changes. Key functions involved in this synchronization include:
upsertWorkspaceBilling: Updates subscription status and metadata for Polar integrations.applyWorkspaceCreditTopup: An atomic RPC call that increases the credit balance and logs the source of the top-up.markContactUnsubscribed: Persists a record incontact_unsubscribeswhen a bounce or complaint is reported via SNS.insertEvent: Logs specific SES event details (timestamp, type, detail) for the campaign history view.
Sources: src/lib/db.ts:810-820, src/lib/db.ts:1005-1020, src/lib/db.ts:1080-1105
Security and Verification
Both webhook endpoints implement verification layers to prevent unauthorized data manipulation:
- SNS Verification: The route handles
SubscriptionConfirmationmessages from AWS. It requires valid signatures for allNotificationmessages to ensure they originated from the configured SNS topic. - Polar Verification: The route uses
validatePolarWebhookEventwith aPOLAR_WEBHOOK_SECRET. If the signature is invalid, it returns a403 Forbiddenresponse.
Sources: src/app/api/webhooks/sns/route.ts, src/app/api/webhooks/polar/route.ts:115-125, README.md:65-70
The Webhooks API is essential for the "hands-off" operation of Send Again, automate-handling everything from billing top-ups to delivery failure suppressions without requiring manual intervention from the workspace owner.