Skip to content
Ritesh FirodiyaGet in touch

Work / Chitragupt / Wiki / Synthesis

transactional-email

Synthesiscanonicalverified 2026-09-21

SYNTHESIS.TRANSACTIONAL-EMAIL

Transactional email spec

This file is the source of truth for every user-visible email Chitragupt sends. Each email below has: trigger, audience, channel-of-truth, subject template, and body sketch.

Email design is intentionally plain HTML + plain text (multipart) — no marketing-style hero banners. Keeps deliverability high and renders cleanly in Gmail, Outlook, and any client.

Sender identity (consistent for all):

From: Chitragupt <hello@chitragupt.ai>
Reply-To: support@chitragupt.ai
List-Unsubscribe: <mailto:unsub-{user_id}@in.chitragupt.ai>, <https://chitragupt.ai/u/unsub/{token}>

Even though we don't send marketing, the List-Unsubscribe header is required by Gmail/Yahoo bulk-sender rules. The unsub endpoint disables optional categories, not service mail.


1 · Auth · email OTP

  • Trigger: user enters email on sign-in or sign-up
  • Audience: prospective + existing users
  • Wireframe: auth/sign-in.html, auth/verify-email.html
  • Subject: Your Chitragupt sign-in code
  • Sketch:
    Hi {name_or_blank},
    
    Your 6-digit code is: {otp_code}
    
    It expires in 10 minutes. If you didn't request this, you can ignore the email.
    
    — Chitragupt
    

2 · Onboarding · welcome (after DPDP consent)

  • Trigger: first time user agrees to DPDP consent and completes step 1
  • Subject: Welcome to Chitragupt, {first_name}
  • Sketch: short — pillar overview + your private forward address (settings/settings-email-forward-setup.html) + link to first-doc-upload.

3 · Inbox · document parsed

  • Trigger: a doc finishes parsing and is routed
  • Wireframe: app/review/document-parsed.html, app/review/document-parsed.html, app/notifications.html
  • Subject: {doc_label} parsed · {pillar} updated
    • e.g. Form 16 parsed · Tax updated
  • Sketch: 1-line summary of extracted data + "Review →" link.
  • Channel honoured: respects user's "Document parsed · email" setting in app/settings/settings-notifications.html. Default: off (push only).

4 · Inbox · parse failed

  • Trigger: doc fails parser pipeline (low confidence, unsupported, OCR error)
  • Wireframe: app/inbox/inbox-populated.html
  • Subject: Couldn't parse {doc_filename}
  • Sketch: short reason + Retry / Report / Raise-Ticket links (mirrors the in-app three-action set).
  • Channel honoured: default on for email (failures need attention).

5 · Inbox · password required

  • Trigger: forwarded or uploaded doc is encrypted and waiting
  • Wireframe: app/inbox/inbox-populated.html
  • Subject: Unlock {doc_filename} to continue parsing
  • Sketch: link to password prompt + reminder of common formats (PAN+DOB).

6 · Email forward · verification

  • Trigger: user sets up email forwarding (clicks "Send test email")
  • Wireframe: app/settings/settings-email-forward-verify.html
  • Subject: [Chitragupt] Verify your email forwarding
  • Body: instructions to forward this email back to the user's private address; brief explainer of approved senders.

7 · Email forward · received receipt (first time + optional)

  • Trigger: an inbound email lands on the user's private address
  • Wireframe: app/settings/settings-email-forward-received.html
  • Subject: Got it · {attachment_count} attachments from {sender}
  • Sketch: lists attachments and their routing. Default: send only for the first 3 forwards, then suppress (to avoid noise) unless the user opts back in.

8 · Tax · action needed

  • Trigger: regime decision approaching, advance tax due, notice received, TDS mismatch detected
  • Wireframe: app/tax/tax-review.html — TDS-mismatch and notice variants are data-driven on the single canonical tax-review screen (2026-06-12 collapse)
  • Subject: Action needed · {short_reason}
    • e.g. Action needed · TDS mismatch found · AY 2026-27
  • Sketch: one-liner + open-tax link. Same content as in-app notification.

9 · Tax · filing window

  • Trigger: 60 / 30 / 7 days before due date
  • Subject: {n} days left to file your AY {ay} return

10 · CA · matched / replied

  • Trigger: CA matched after Ask CA payment, or CA posts a message
  • Subject: {ca_first_name} {ca_last_initial} replied to your {question_topic} question
  • Sketch: snippet (first 200 chars) of the CA's message + link.

11 · Payment · success (with GST invoice attached)

  • Trigger: any successful Razorpay capture
  • Wireframe: payment/payment-success.html, app/settings/settings-invoice-detail.html
  • Subject: Payment received · ₹{amount} · invoice INV-{nnn}
  • Attachment: GST invoice PDF · attached every time (this is the auto-email).
  • Audience: user + their linked CA (if a CA grant covers the household).
  • Sketch: amount, what was unlocked, refund window dates, link to billing.

12 · Payment · failure

  • Trigger: Razorpay returns failure or webhook fails to capture
  • Wireframe: payment/payment-failed.html
  • Subject: Payment didn't go through · {amount}
  • Sketch: reason + retry link. We don't auto-retry without user action.

13 · Payment · refund processed

  • Trigger: refund is initiated (within the 14-day window or per support discretion)
  • Wireframe: payment/refund-success.html
  • Subject: Refund of ₹{amount} initiated · credit note CN-{nnn}
  • Attachment: credit note PDF.

14 · Billing · renewal coming up

  • Trigger: 7 days before auto-renewal (Pro / Pro Family annual mandate)
  • Wireframe: app/settings/settings-billing.html
  • Subject: Your Chitragupt Pro renews on {date}
  • Sketch: amount + dates + link to cancel / change plan. RBI rule: pre-debit notification 24h before charge is also a separate transactional ping (see #15).

15 · Billing · pre-debit (RBI mandate)

  • Trigger: 24 hours before any recurring auto-debit (UPI AutoPay / e-NACH / card-on-file)
  • Subject: Heads-up · ₹{amount} will debit tomorrow for Chitragupt Pro
  • Required by RBI for any recurring mandate · do not suppress · channel: email + SMS.

16 · Family · invited / accepted / role changed

  • Trigger: invite sent, accepted, declined, role changed, member removed
  • Wireframe: app/settings/settings-family-invite.html, app/settings/settings-family-members.html, app/settings/settings-family-pending.html
  • Subject: varies per event · e.g. {name} joined Sharma household as Editor
  • Audience: household owner + the affected member.

17 · Family · dissolution proposed (7-day grace)

  • Trigger: any member triggers household dissolution
  • Wireframe: app/settings/settings-family-leave.html
  • Subject: Sharma household will dissolve in 7 days · you can stop it
  • Audience: all members except the initiator · email + push, every channel.

18 · Sharing · CA grant given / revoked

  • Trigger: user grants or revokes a CA share
  • Wireframe: app/settings/settings-sharing.html
  • Subject: depends · user + CA both notified.

19 · Account · deletion requested (30-day grace)

  • Trigger: user requests account deletion
  • Wireframe: app/settings/settings-account-deletion.html, patterns/confirm-destructive.html
  • Subject: Your Chitragupt account is scheduled for deletion on {date}
  • Body: 30-day undo window + link to cancel the deletion.

20 · DPDP · data export ready

  • Trigger: user requests full data export (DPDP Act right to access)
  • Subject: Your Chitragupt data export is ready
  • Body: signed download link, expires in 7 days.

21 · App update · breaking

  • Trigger: server forces a breaking client refresh
  • Subject: usually no email · this is an in-tab event. Email only if user's session is offline for >7 days and security patch requires re-auth.

Suppressed / never sent

  • Marketing newsletters · the optional "occasional product updates" consent (DPDP step) is the only non-service email we may send. It opts in to a 1-per-quarter cadence max.
  • Engagement nags ("you haven't filed yet", "your streak is 5 days") · not in scope.
  • Cross-sell of CA services beyond the user's own current case.

Operational rules

  • Every email includes the same footer: company legal name, GSTIN, CIN, registered address, grievance officer email — required by Indian e-commerce and DPDP norms.
  • Quiet hours (10pm–8am local) apply to push only; email goes whenever, since it's pull-not-interrupt.
  • Bounce / complaint handling: 3 hard bounces → suspend email until user updates address; 1 complaint (spam button) → auto-disable all optional categories and flag for review.

Build notes (not in wireframe scope)

  • ESP candidates: AWS SES (cheapest, India region), Postmark (best deliverability for transactional), Resend (modern API, good DX).
  • For GST-invoice attachments, render PDF server-side from the same canonical invoice JSON used by settings-invoice-detail.html — never re-derive in two places.
  • DKIM + SPF + DMARC enforced before any prod sends.

Every project of mine is written down like this.

Read the résumé