{team.displayName}
Team ID: {team.id}
All teams{key.description}
Last 4 digits: {key.value.lastFour}
Created: {key.createdAt.toLocaleDateString()}
{key.description}
Last 4 digits: {key.value.lastFour}
Created: {key.createdAt.toLocaleDateString()}
{key.description}
Last 4 digits: {key.value.lastFour}
Created: {key.createdAt.toLocaleDateString()}
Thanks for joining us.
', }); ``` ### Send to all users ```typescript theme={null} await hexclaveServerApp.sendEmail({ allUsers: true, templateId: 'your-template-id', subject: 'We just shipped a big update', variables: { featureName: 'Dark mode', }, }); ``` ### Send from a dashboard draft If you've composed an email in the dashboard's draft editor, you can trigger it programmatically: ```typescript theme={null} await hexclaveServerApp.sendEmail({ userIds: ['user-id'], draftId: 'your-draft-id', }); ``` ### Full options ```typescript theme={null} await hexclaveServerApp.sendEmail({ // Recipients - exactly one of these is required: userIds: ['user-id-1'], // specific users // allUsers: true, // or all users in your project // Content - exactly one of these is required: html: 'Hello!
', // raw HTML // templateId: 'template-id', // or a template with variables // draftId: 'draft-id', // or a dashboard draft // Optional: subject: 'Hello!', variables: { key: 'value' }, themeId: 'theme-id', // apply a specific theme // themeId: null, // use the default theme // themeId: false, // send with no theme at all notificationCategoryName: 'Marketing', scheduledAt: new Date('2025-12-25T00:00:00Z'), }); ``` ### `SendEmailOptions` type shape ```typescript theme={null} type SendEmailOptions = { userIds: string[]; // users to send to themeId?: string | null | false; // theme override subject?: string; // subject line notificationCategoryName?: string; // preference category html?: string; // raw HTML body templateId?: string; // template ID variables?: RecordHello!
', subject: 'Test Email', }); if (result.status === 'error') { switch (result.error.code) { case 'REQUIRES_CUSTOM_EMAIL_SERVER': console.error('Please configure a custom email server'); break; case 'SCHEMA_ERROR': console.error('Invalid email data provided'); break; case 'USER_ID_DOES_NOT_EXIST': console.error('One or more user IDs do not exist'); break; } } ``` ## Scheduling Pass a `scheduledAt` date to delay delivery. The email enters the pipeline immediately but won't be sent until the scheduled time. ```typescript theme={null} await hexclaveServerApp.sendEmail({ userIds: ['user-id'], html: 'Happy New Year!
', subject: 'Happy New Year!', scheduledAt: new Date('2026-01-01T00:00:00Z'), }); ``` If `scheduledAt` is omitted, the email is sent as soon as possible. ## Email pipeline Emails are processed asynchronously through a multi-stage pipeline: 1. **Enqueue** - The email is saved to the outbox with its template, recipients, and scheduling metadata. 2. **Render** - The template TSX is compiled into HTML, subject, and plain text. 3. **Queue** - Rendered emails whose scheduled time has passed are queued for delivery, respecting your project's sending capacity. 4. **Send** - Emails are delivered, honoring notification preferences and skipping users who have unsubscribed. 5. **Track** - Delivery events (sent, opened, clicked, bounced, marked as spam) are recorded. You can monitor every email's status in the dashboard under **Emails → Sent**. ## Templates Templates are React Email components written in TSX. Each template receives the current `user`, `project`, and any custom `variables` you pass when sending. ```tsx theme={null} import { type } from "arktype"; import { Container } from "@react-email/components"; import { Subject, NotificationCategory, Props } from "@hexclave/emails"; export const variablesSchema = type({ featureName: "string", }); export function EmailTemplate({ user, project, variables, }: PropsHi {user.displayName}, check out {variables.featureName}!
Check out our new feature!
', subject: 'Product Updates', notificationCategoryName: 'Marketing', }); ``` If a user has unsubscribed from Marketing emails, the email will be automatically skipped during delivery. Marketing emails always include an unsubscribe link. ## React components integration Emails integrate with Hexclave UI components automatically (for example verification, password reset, and magic-link flows).\ For custom flows, trigger `sendEmail` from your server code: ```typescript theme={null} import { hexclaveServerApp } from '@hexclave/next'; // replace `next` with the correct framework SDK package export async function inviteUser(userId: string) { const result = await hexclaveServerApp.sendEmail({ userIds: [userId], templateId: 'invitation-template', subject: "You're invited!", variables: { inviteUrl: 'https://yourapp.com/invite/token123', }, }); return result; } ``` ## Email server configuration Configure your email server in the dashboard under **Emails → Email Settings**. There are four options: ### Shared (development only) The default for new projects. Emails are sent from `noreply@sent-with-hexclave.com` using Hexclave's shared infrastructure. Good for development - not suitable for production. ### Custom SMTP Connect any SMTP provider. Configure: * **Host** - e.g. `smtp.sendgrid.net` * **Port** - typically 587 (STARTTLS) or 465 (implicit TLS) * **Username** and **Password** * **Sender email** and **Sender name** ### Resend Connect your [Resend](https://resend.com) account by entering your API key. Hexclave configures the SMTP connection automatically. ### Managed Let Hexclave manage your email domain. Hexclave handles DNS configuration and deliverability for you. Set up requires: 1. Choose a subdomain (e.g. `mail.yourapp.com`) 2. Add the DNS records Hexclave provides 3. Verify the domain in the dashboard{credits.nonNegativeQuantity}
Team Name: {team.displayName}
You are a member of this team.
Setting up with AI? Use this single prompt:
Choose all that apply.
Select a tool to show setup instructions.
Loading...
: data.length === 0 ?No notes found
: data.map((note) =>You are signed in
User ID: {user.id}
> ) : ( )}Welcome, {user.displayName ?? "unnamed user"}
Your e-mail: {user.primaryEmail}
You are not logged in
Welcome, {user.displayName ?? "unnamed user"}
Your e-mail: {user.primaryEmail}
You are not logged in
Loading...
: data.length === 0 ?No notes found
: data.map((note) =>You are signed in
User ID: {user.id}
> : }You are not signed in.
; } returnHello, {user.displayName ?? user.primaryEmail ?? user.id}
; } ```Hello, {user.displayName ?? user.primaryEmail ?? user.id}
; } ```Please sign in.
; } returnHello, {user.displayName ?? user.primaryEmail ?? user.id}
; } ```Hello, {user.displayName ?? user.primaryEmail ?? user.id}
; } ```You are not a member of this team.
; } return (Team ID: {team.id}
All teamsYou are not a member of this team.
; } return (Team ID: {team.id}
All teamsWorkspace not found.
; } const canExport = await user.getPermission(team, "export_reports"); if (!canExport) { returnYou do not have access to exports in this workspace.
; } return ; } ```Workspace not found.
; } returnAgent-first setup
Copy the full Hexclave setup prompt into your coding agent, or follow the manual instructions.
Start at the top and work your way down, or jump straight to the section you need.
First-time setup, install the SDK, get auth running in minutes.
Compare development flows, configure your project, and use lower-level interfaces where needed.
Use hooks, objects, and types to read and write auth data directly in your app code.
Integrate Hexclave from any backend or language through HTTP endpoints and webhook flows.
Reach for product access, source code, and support channels when you need more than reference docs.
Thanks for joining us.
", }); if (htmlResult.status === "error") { console.error("Failed to send email:", htmlResult.error); } ``` ```typescript theme={null} const templateResult = await hexclaveServerApp.sendEmail({ userIds: ["user-1"], templateId: "welcome-template", variables: { userName: "John Doe", activationUrl: "https://app.com/activate/token123", }, }); ```Thanks for signing up!
", }); ```