Notifications
Passenger notifications close the loop. Nexa sends two kinds of email per case:
- Disruption acknowledgement — "your flight was cancelled, your next flight is X, we're finding you a room."
- Voucher — "your hotel is X, check-in at Y, here's the confirmation code."
Channels
SendGrid is the default email provider; sandbox tenants use a deterministic limited delivery channel so you can drive the whole pipeline without real credentials. SMS via Twilio is available on request and configured per tenant.
Idempotency
Every send is deduplicated on (groupId, type, channel, reservationUrn):
- Re-running a case never double-emails passengers.
- Operators can safely retry stuck notifications.
- Providers' own deduplication (e.g. SendGrid's message-id) is used as a secondary guard.
Localization
Templates are keyed by airlineCode + locale. When the airline's DCS sends a passenger preferred language, Nexa uses it; otherwise it falls back to the airport's default language, then English.
Templates use a simple {{variable}} syntax over a shared layout. Tenants edit them in the operations console (under Notifications → Templates) and changes are versioned automatically. The layout includes:
- Airline branding (logo, colors, legal footer)
- A QR code with the reservation URN (useful for hotel front-desk verification)
- A multilingual greeting based on the passenger's preferred language
Voucher payload
The voucher email contains:
- Confirmation code (large and scannable)
- Hotel name, address, phone, and a static map tile
- Check-in / check-out dates with explicit timezone
- Reaccommodated flight: number, date, gate (if known), terminal
- Ground transport block if the case has one (see Transport)
- Corporate-guarantee notice or card-on-file confirmation
- Passenger list
- Contact for changes (airline support or ops line)
Monitoring delivery
curl "https://us-central1.api.nexastudio.io/notifications/case/$CASE_URN" \
-H "Authorization: Bearer $TOKEN" | jq
Per-notification fields:
| Field | Meaning |
|---|---|
status | PENDING, SENT, FAILED, BOUNCED |
providerMessageId | SendGrid message ID for cross-reference |
attempts[] | Each retry with timestamp and error |
openedAt, clickedAt | Populated when SendGrid reports engagement (optional) |
Operator actions
- Resend —
POST /notifications/:urn/resendwith a reason. Bypasses the idempotency guard by issuing a new notification rather than re-sending the same one, so the audit trail is preserved. - Edit template — Only
ADMINcan push template changes. Edits in the operations console are versioned and applied immediately.
Deliverability hygiene
- Use a dedicated SendGrid sub-user per airline so bounces on one tenant don't hurt others.
- Enable SPF, DKIM, and DMARC on the sending domain (the Nexa team handles this during tenant onboarding).
- Warm new IPs before a major disruption — cold IPs + sudden volume equals spam folder.