Skip to main content

Overview

The Email Subscription API allows users to subscribe to daily Bhagavad Gita verse emails delivered at 8am in their local timezone. Emails are sent via Resend using a cron job system.

Daily Delivery

Emails sent at 8am in user’s selected timezone

Smart Selection

Prioritizes unseen verses from user’s query history

One-Click Unsubscribe

Every email includes an unsubscribe link

30+ Timezones

Support for all major worldwide timezones

Check Subscription Status

GET /api/email-subscription
endpoint
Check if the current user is subscribed to daily emails

Authentication

Required: Yes (Clerk session token)

Rate Limit

10 requests per minute

Response

status
string
Always “success”
subscribed
boolean
true if subscribed, false otherwise
timezone
string | null
User’s selected timezone (e.g., “America/New_York”) or null if not subscribed

Example Request

curl https://gitachat.org/api/email-subscription \
  -H "Authorization: Bearer YOUR_SESSION_TOKEN"

Example Response

{
  "status": "success",
  "subscribed": true,
  "timezone": "America/New_York"
}

Subscribe to Daily Emails

POST /api/email-subscription
endpoint
Subscribe the current user to daily verse emails

Authentication

Required: Yes (Clerk session token)

Rate Limit

10 requests per minute

Request Body

timezone
string
required
IANA timezone identifier (e.g., “America/New_York”, “Europe/London”, “Asia/Tokyo”)See List of Timezones for all valid values.

Response

status
string
Always “success”
message
string
Confirmation message

Example Request

curl -X POST https://gitachat.org/api/email-subscription \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_SESSION_TOKEN" \
  -d '{
    "timezone": "America/Los_Angeles"
  }'

Example Response

{
  "status": "success",
  "message": "Subscribed to daily emails"
}

Unsubscribe from Emails

DELETE /api/email-subscription
endpoint
Unsubscribe the current user from daily emails

Authentication

Required: Yes (Clerk session token)

Rate Limit

10 requests per minute

Response

status
string
Always “success”
message
string
Confirmation message

Example Request

curl -X DELETE https://gitachat.org/api/email-subscription \
  -H "Authorization: Bearer YOUR_SESSION_TOKEN"

Example Response

{
  "status": "success",
  "message": "Unsubscribed from daily emails"
}

One-Click Email Unsubscribe

GET /api/unsubscribe?token=TOKEN
endpoint
Unsubscribe via the token included in email links (no authentication required)

Query Parameters

token
string
required
Unsubscribe token included in email footer links

Response

Returns an HTML page confirming the unsubscription (not JSON).

Example Request

curl https://gitachat.org/api/unsubscribe?token=abc123xyz789

Email Delivery System

Cron Job Endpoint

Daily emails are sent via an automated cron job: Endpoint: POST /api/daily-email
Authentication: Requires CRON_SECRET environment variable
Schedule: Runs every hour to catch all timezones
The cron job:
  1. Queries all subscriptions where it’s 8am in their timezone
  2. Fetches their daily verse (prioritizing unseen verses)
  3. Sends email via Resend
  4. Updates last_sent timestamp

Email Content

Each daily email includes:
  • Chapter and verse reference
  • Full verse translation
  • Brief AI-generated summary
  • Link to view full verse on GitaChat
  • One-click unsubscribe link

Supported Timezones

GitaChat supports 30+ worldwide timezones including:
  • Americas: America/New_York, America/Chicago, America/Denver, America/Los_Angeles, America/Toronto, America/Vancouver, America/Mexico_City, America/Sao_Paulo
  • Europe: Europe/London, Europe/Paris, Europe/Berlin, Europe/Madrid, Europe/Rome, Europe/Amsterdam, Europe/Brussels, Europe/Stockholm
  • Asia: Asia/Kolkata, Asia/Dubai, Asia/Tokyo, Asia/Shanghai, Asia/Hong_Kong, Asia/Singapore, Asia/Seoul, Asia/Bangkok, Asia/Jakarta
  • Pacific: Australia/Sydney, Australia/Melbourne, Pacific/Auckland, Pacific/Fiji
  • Africa: Africa/Cairo, Africa/Johannesburg

Database Schema

Subscriptions are stored in Supabase email_subscribers table:
FieldTypeDescription
user_idtextPrimary key (Clerk user ID)
emailtextUser’s email address
timezonetextIANA timezone identifier
subscribed_attimestampSubscription timestamp
last_senttimestampLast email sent timestamp

Error Codes

Status CodeDescription
200Success
400Invalid timezone or missing parameters
401Unauthorized (authentication required)
429Rate limit exceeded (10/minute)
500Database error or email service failure

Usage Notes

Users must have a verified email address in Clerk to receive daily emails.
The timezone setting applies to the email delivery time. The daily verse itself is consistent across all timezones on any given UTC date.
Unsubscribe tokens are one-time use and expire after successful unsubscription.

Implementation Reference

Source Files:
  • Subscription API: frontend/app/api/email-subscription/route.ts
  • Unsubscribe: frontend/app/api/unsubscribe/route.ts
  • Cron job: frontend/app/api/daily-email/route.ts
  • Settings UI: frontend/app/settings/page.tsx

Build docs developers (and LLMs) love