Resend (Email Notifications)
Resend is the transactional email provider for Client Portal. It sends booking confirmations, meeting reminders, feedback requests, and onboarding emails via a clean API with ICS calendar attachment support.
API Configuration
| Setting | Value |
|---|---|
| API URL | https://api.resend.com/emails |
| Auth | Authorization: Bearer {RESEND_API_KEY} |
| Env Variable | RESEND_API_KEY (Supabase secret) |
| From Domain | 1hourrecruitment.com |
Edge Functions
send-booking-notification
Purpose: Sends booking confirmation and notification emails when a meeting is booked. Handles both client and internal booking flows.
Request
{
"meeting_id": "uuid (client meetings)",
"sales_meeting_id": "uuid (internal meetings)",
"booker_timezone": "America/New_York",
"origin_url": "https://client-hub.1hourrecruitment.com"
}
Exactly one of meeting_id or sales_meeting_id must be provided.
Emails Sent
For each booking, two emails are sent:
| To | Subject | From | |
|---|---|---|---|
| Confirmation | Booker (prospect) | Meeting Confirmed: {title} | {Client Name} <[email protected]> |
| Notification | Owner (client or user) | New Booking: {name} booked an intro call | 1HR Recruitment <[email protected]> |
Reply-To Logic
Reply-to address is determined by priority:
booking_links.reply_to_email(custom per booking link)user_profiles.reply_to_email(internal mode) orclients.primary_contact_email(client mode)- Auth user email (fallback for internal mode)
ICS Calendar Invite
The confirmation email includes an ICS file attachment with METHOD:REQUEST, which auto-adds the meeting to the booker's calendar in most email clients:
BEGIN:VCALENDAR
VERSION:2.0
METHOD:REQUEST
BEGIN:VEVENT
UID:{meetingId}@1hourrecruitment
DTSTART:20260215T140000Z
DTEND:20260215T143000Z
SUMMARY:Intro Call with 1 Hour Recruitment
ORGANIZER;CN=1 Hour Recruitment:mailto:[email protected]
ATTENDEE;RSVP=TRUE;CN=John Doe:mailto:[email protected]
STATUS:CONFIRMED
END:VEVENT
END:VCALENDAR
Calendar Add Links
The confirmation email also includes direct "Add to Calendar" links:
- Google Calendar:
https://calendar.google.com/calendar/render?action=TEMPLATE&text=...&dates=... - Outlook.com:
https://outlook.live.com/calendar/0/action/compose?rru=addevent&subject=...
Reschedule/Cancel Link
If the meeting has a cancel_token, the confirmation email includes a manage link:
{origin_url}/booking/manage/{cancel_token}
Custom Templates
Before sending, the function checks for custom email templates in the email_templates table:
const custom = await resolveTemplate(supabase, "booking-confirmation-booker", {
booker_name: "John",
meeting_title: "Intro Call",
date: "Wed, 15 Feb 2026",
time: "2:00 PM EST",
// ...
});
| Template Key | Purpose |
|---|---|
booking-confirmation-booker | Confirmation to the person who booked |
booking-confirmation-owner | Notification to the meeting owner |
Templates support {{variable}} placeholders that get replaced at send time.
Contact History Enrichment (Client Mode)
For client bookings, if the booker's phone matches existing contacts, the owner notification email includes a "Existing Contacts" section with matching records from the contacts table, including their market assignment.
send-onboarding-email
Purpose: Sends a welcome email to new client contacts with a link to complete their scheduling setup (calendar connection, availability, meeting preferences).
Request
{
"client_id": "uuid",
"client_name": "Smith Legal Search",
"contact_name": "John Doe",
"contact_email": "[email protected]",
"onboarding_url": "https://client-hub.1hourrecruitment.com/onboarding/abc123"
}
Email Content
From: 1 Hour Recruitment <[email protected]>
Subject: Complete your scheduling setup for Smith Legal Search
Hi John,
You've been added as the primary contact for Smith Legal Search.
Complete a quick onboarding setup to start scheduling intro calls.
This includes:
- Connecting your calendar
- Setting your available hours
- Choosing your meeting method
[Complete Setup]
Side Effects
After sending, updates team_members.onboarding_email_sent_at for tracking.
send-meeting-reminder
Purpose: Sends reminder emails before upcoming meetings.
Reminder Schedule
| Timing | Column Updated |
|---|---|
| 24 hours before | reminder_24h_sent_at |
| 1 hour before | reminder_1h_sent_at |
Reminders are triggered by a scheduled job (cron) that queries for meetings with upcoming scheduled_for timestamps where the corresponding reminder column is null.
Email Design System
All booking emails use a consistent branded design:
| Element | Value |
|---|---|
| Logo | 1HR Recruitment color logo (from Supabase Storage) |
| Font | Inter, system fallback stack |
| Accent color | #161616 (near black) |
| Text color | #0d0d0d |
| Subtext color | #6b7280 |
| Border color | #e5e5e5 |
| Layout | Max 480px card with 4px top accent stripe |
The email includes a preheader (hidden text for email client preview), branded card layout with detail rows using a colored left-border accent, and CTA buttons.
From Addresses
| Function | From Address |
|---|---|
| Booking confirmation (client) | {Client Name} <[email protected]> |
| Booking confirmation (internal) | 1 Hour Recruitment <[email protected]> |
| Booking notification to owner | 1HR Recruitment <[email protected]> |
| Onboarding email | 1 Hour Recruitment <[email protected]> |
Error Handling
- Email send failures are logged but do not block the booking flow.
- The
confirmation_sent_attimestamp is only set if the booker email sends successfully. - Resend API errors include error codes and messages in the response body.
Related Documentation
- Calendar OAuth -- Booking system that triggers email notifications
- Close CRM -- Lead creation triggered alongside booking notifications