Messaging Terms & Consent Wording — DRAFT
Draft for lawyer review. Not legal advice. Replace everything in [brackets]. Last synced with the code: 2026-10-23.
Why this matters:
- TCPA: the federal Telephone Consumer Protection Act. It applies to automated text messages; how it applies to iMessage specifically (and to a business-initiated sign-in code sent over iMessage) is worth confirming with counsel. See
LAWYER-QUESTIONS.md.- Apple’s terms: our iMessage setup runs on our own Mac (“bridge Mac”) signed in to a business Apple ID. Apart from the one sign-in code in §1b, users message us first.
- WhatsApp is deferred (no Meta/WhatsApp Business setup until the iMessage pilot validates demand). The WhatsApp wording in §7 is kept for later and is not live. WhatsApp users are offered a waitlist.
Keep the exact text users agreed to. Each consent’s version string and the SHA-256 hash of its exact text are stored in
consents. The source of truth for live wording is the code:packages/auth/src/consent-text.tsandpackages/auth/src/otp-consent-text.ts. Changing any wording means bumping its version.
1. Website sign-in page
The page offers two ways to sign in. Each has its own consent text shown directly above its button. Tapping the button counts as agreement; there’s no pre-checked box. Both are protected by Cloudflare Turnstile (CAPTCHA) and rate limits.
1a. “Text to sign in” (user texts us first) — version signin-2026-10-26
The user taps a button that opens Messages with a prefilled one-time code and sends it to us.
By tapping Text to sign in, you agree to our [Terms of Service] and [Privacy Policy], confirm you’re 18 or older, and agree to receive messages from Tack about your account and the requests you make, including automated messages, at the iMessage address you use. Message frequency varies. Message and data rates may apply. Reply STOP to opt out or HELP for help. Consent isn’t a condition of purchase.
Note for counsel/engineering: this live text still names the WhatsApp button, which is hidden while WhatsApp is deferred. Consider an iMessage-only version (new version string) before launch.
1b. “Phone number + code” (we iMessage the user a code) — version otp-signin-2026-10-26
The user types their phone number and taps Send code. We send one iMessage with a 6-digit code to that number. This is the only message we start before the user has texted us.
We’ll iMessage you a code to sign in. By tapping Send code, you agree to our [Terms of Service] and [Privacy Policy], confirm you’re 18 or older, and agree to receive messages from Tack about your account and the requests you make, including automated messages, at the number you enter. Message frequency varies. Message and data rates may apply. Reply STOP to opt out or HELP for help. Consent isn’t a condition of purchase.
The code message itself (plain text, names the brand, no links):
Your Tack sign-in code is [123456]. It expires in 10 minutes. If you didn’t ask for this, ignore this message.
Spanish version of the code message (sent when the page is in Spanish):
Tu código para iniciar sesión en Tack es [123456]. Vence en 10 minutos. Si no lo pediste, ignora este mensaje.
Safeguards built in:
- Code is 6 random digits, single use, expires in 10 minutes, and stops working after 5 wrong tries.
- Stored only as a hash bound to the browser session that asked for it.
- Send limits: 3 per number per 10 minutes, 10 per number per day, 10 per IP per hour, plus a global hourly cap.
- Consent (§1b text) is recorded only once the code is verified.
Language of the consent texts
The sign-in page is available in English and Spanish, but the consent texts are English-only for now. On the Spanish page the English consent text is shown (marked as English). A Spanish consent text will get its own version string and hash once a lawyer and a native speaker approve it (draft in legal/es/messaging-consent.md).
2. Profile form (after sign-in)
Collects name, email and date of birth (must be 18+). It no longer asks for a mailing address.
Required checkbox — version profile-required-2026-10-26:
☐ I confirm I’m 18 or older and agree to the [Terms of Service] and [Privacy Policy]. I understand Tack uses AI to understand my messages and act in the tools I connect, and that I should review confirmations before approving them.
Optional checkbox, unchecked by default — version daily-brief-2026-10-26:
☐ Send me a daily summary each morning (you can change the time or turn it off anytime).
Not built yet; only add if we’ll send product news:
☐ Send me occasional product updates and tips. (Up to [2] per month. Reply STOP anytime.)
3. First welcome message (after sign-in)
iMessage, English (the contact-card sentence appears only when the .vcf card was actually sent):
Hi [first name] 👋 You’re in. I’m Tack — text me what you need done and I’ll handle it in your tools. Save my contact card above so you know it’s me. Finish setup here (1 min): [link] Msg frequency varies. Reply HELP for help, STOP to opt out.
iMessage, Spanish:
Hola, [nombre] 👋 Ya quedó. Soy Tack: escríbeme lo que necesitas y yo lo hago en tus herramientas. Guarda mi tarjeta de contacto de arriba para que sepas que soy yo. Termina la configuración aquí (1 min): [link] La frecuencia de mensajes varía. Responde AYUDA para ayuda o ALTO para darte de baja.
4. Keyword replies (handled before the AI agent sees the message)
A keyword counts only when it is the whole message (case-insensitive, trailing punctuation and Spanish ¡ ¿ ignored). “Stop the job” or “please stop” go to the agent instead. Replies use the user’s language; each user has a saved language (English or Spanish), detected from their messages or set by asking (“en español”, “English please”).
| User sends | Action | English reply | Spanish reply |
|---|---|---|---|
| STOP, STOPALL, UNSUBSCRIBE, END, QUIT · ALTO, PARAR, DETENER, BAJA | Revoke consent for this channel (consents.revoked_at); stop all proactive messages; agent disabled on this channel |
“You’re unsubscribed from Tack on this channel and won’t get more messages. Reply START to resume.” | “Te diste de baja de Tack en este canal y ya no recibirás mensajes. Responde INICIAR para volver a recibirlos.” |
| START, UNSTOP · INICIAR, REANUDAR | Restore consent (new consents row) |
“Welcome back — you’re resubscribed. Text me anytime.” | “Qué bueno tenerte de vuelta: ya vuelves a recibir mensajes. Escríbeme cuando quieras.” |
| HELP · AYUDA · INFO (either language) | — | “Tack help: text what you need done, or visit asktack.com/docs. Support: support@asktack.com. Reply STOP to opt out.” | “Ayuda de Tack: escríbeme lo que necesitas o visita asktack.com/docs. Soporte: support@asktack.com. Responde ALTO para darte de baja.” |
| CANCEL · CANCELAR | Not treated as an opt-out by itself. We ask which they meant. | “Did you mean cancel the pending action, or stop all messages? Reply STOP to stop all messages.” | “¿Quieres cancelar la acción pendiente o dejar de recibir todos los mensajes? Responde ALTO para no recibir más mensajes.” |
Notes:
- CANCEL is a STOP word in SMS carrier practice. Here it usually means “cancel that job,” so we ask instead of opting out. Counsel should confirm that’s acceptable for iMessage (see
LAWYER-QUESTIONS.md). - Natural-language opt-outs (“stop texting me”, “no me escribas más”) are handled by the agent, which should treat clear requests as STOP. [Confirm whether counsel wants these handled as hard keywords.]
5. Team invites (Crew plans)
Invites are sent by the inviting user from their own phone (a prefilled sms: link), not by us, so the invitee has a relationship with the sender.
[Owner name] invited you to [Company] on Tack — text it to log jobs, photos and invoices. Join: [invite link]
The invitee gives their own consent through the sign-in page (§1) before we ever message them.
6. Referral invites
Same rule as team invites: the user sends the invite. We never text a referred person until they sign in themselves.
7. WhatsApp template wording — DEFERRED, not live
Kept for when WhatsApp launches (submit to Meta for approval then). Meta’s WhatsApp Business policies require opt-in before business-initiated messages; honor blocks and reports, and stop sending templates to anyone who opts out.
| Template name | Category | Text |
|---|---|---|
signin_code |
Authentication | “{{1}} is your Tack sign-in code. It expires in 10 minutes.” (with a copy-code button) |
daily_brief_ready |
Utility | “Good morning {{1}} — your daily summary is ready. Reply to see it.” |
task_finished |
Utility | “Update on your request: {{1}}. Reply for details.” |
connection_expiring |
Utility | “Your {{1}} connection expires on {{2}}. Reply RECONNECT to keep it working.” |
billing_issue |
Utility | “There’s a problem with your Tack payment. Update it here to keep things running: {{1}}” |
8. Records we keep
For each consent (consents table):
- user and channel/address;
- kind and version (for example
signin-2026-10-26,otp-signin-2026-10-26,profile-required-2026-10-26); - SHA-256 of the exact text shown;
- timestamp, IP and user agent.
STOP/START events are also written to audit_log.