Messaging & marketing (Customer.io)
Marketing campaigns, behavioral journeys, and multi-channel product alerts are a different concern from one-off transactional mail (host-request approvals, password reset) — and both are different from human @foodtrucknerdz.com correspondence (Gmail send-as).
We use Customer.io as the messaging / marketing automation platform, with Resend kept for critical application transactional email and Twilio as the SMS transport.
Workspace data center: United States (chosen at signup; not changeable later). Matches FTN’s US-first customer and owner base. GDPR still applies if we serve EU users — handle via privacy/consent and DPAs, not by forcing EU hosting.
Product vs human email (do not mix)
| Lane | FTN choice |
|---|---|
App hard transactional (code) |
Resend on sending subdomain |
Marketing / behavioral journeys |
Customer.io (+ Twilio for SMS). Prefer marketing subdomain |
Human correspondence / Gmail send-as |
ZeptoMail (per-user SMTP keys) when needed — not Resend, not Brevo as the default. See Dev-Centr Business Bootstrap email decision matrix on docs.devcentr.org. |
Inbound to personal Gmail |
Cloudflare Email Routing (ops), independent of Resend/Customer.io |
DNS for Resend roles (updates / send / links) and DMARC live in the org infra Pulumi repo (see that component’s Email DNS docs once published on docs.foodtrucknerdz.com).
Channels in scope
Select these in Customer.io (and wire them in product):
| Channel | Role at FTN |
|---|---|
Marketing newsletters, digests, owner onboarding drips, behavioral campaigns. Prefer a marketing subdomain (e.g. |
|
SMS |
Owner account and ops alerts (security, payment failures, host-request outcomes while on the truck). Optional customer “truck nearby” when push is unavailable. Transport: Twilio (Verify for OTPs; Messaging for alerts). Telnyx is a cost alternative later. |
Push |
Primary for time-sensitive location alerts on |
In-app |
Owner dashboard and mobile notification center for non-urgent product messages. |
Out of scope for now: WhatsApp, Slack.
Why Customer.io (vs Brevo / Loops-only / Resend Broadcasts alone)
-
Event-driven journeys fit check-in and “nearby” product moments better than blast-only tools.
-
One orchestration brain for Email + SMS + Push + In-app (avoid sending the same marketing stream from both Resend Broadcasts and Customer.io).
-
Brevo is a classic ESP — fine for list/campaign marketing without product event orchestration; it is the wrong default for FTN’s multi-channel product journeys and a poor fit for human Gmail send-as on cheap tiers.
-
Resend remains the path for hard transactional mail already wired (host requests, etc.) unless we later consolidate.
Split of responsibilities
| System | Owns |
|---|---|
Customer.io |
Marketing, digests, drips, behavioral / multi-channel product messaging. Orchestrates SMS and push; does not replace Twilio or the push provider. |
Resend |
Critical transactional email ( |
Twilio |
SMS delivery and Verify OTPs under Customer.io (or direct from Convex/actions for account codes). |
ZeptoMail (ops) |
Human outbound SMTP when teammates need custom-domain send-as outside the product. |
Adapty / Better Auth / Convex |
Subscriptions, identity, and domain data — emit events into Customer.io; do not use Customer.io as the source of truth for access or memberships. |
Product motivations (roadmap)
-
Time-sensitive location alerts — “favorite truck just checked in nearby.” Email is too slow; push needs the app; SMS covers people not in-app. Primary driver for SMS + Push.
-
Owner account / ops SMS — codes, security, billing, and approval outcomes when owners are running the truck and not checking email.
-
Email marketing — product news, owner nurture, optional opted-in local digests (consent required; see privacy/CMP notes).
Integration checklist (planned)
-
Create Customer.io workspace in the United States data center; enable Email, SMS, Push, In-app only.
-
Connect Twilio for SMS; configure push for
ftn-app; plan in-app surfaces on web + mobile. -
Identify people with the Better Auth / Convex user id (same pattern as Adapty
customer_user_id). -
Emit product events from Convex/actions (e.g.
truck_checked_in,host_request_decided) — do not poll UI state for campaigns. -
Keep marketing (
news.) and transactional (updates.) sending domains separate; wire unsubscribe / SMS STOP compliance. -
Gate marketing and location digests on explicit opt-in; keep admin/security messages on Resend (or transactional CIO templates) as appropriate.
-
Verify Resend domain
updates.foodtrucknerdz.com(return-pathsend, trackinglinks); setFTN_TRANSACTIONAL_FROMaccordingly.
Environment variables (planned)
Document placeholders on Environment variables when secrets are provisioned:
-
Customer.io site/API keys (server-only track / app API as needed)
-
Twilio account + messaging / Verify credentials (if called outside Customer.io)
-
Existing Resend keys remain for transactional mail (
FTN_TRANSACTIONAL_FROM→@updates.foodtrucknerdz.com)
Out of scope
-
Paid plan entitlements (see Subscription management (Adapty))
-
Square POS catalog sync (see POS implementation)
-
Cookie consent CMP (Silktide — separate from marketing ESP)