Operate Your Project
Emails
Configure email providers, control transactional emails, and send branded emails programmatically.
Banata handles transactional email delivery for your authentication flows. You configure a provider, choose which email types to send, and Banata takes care of the rest — delivering magic links, verification emails, password resets, invitation emails, and more through the provider you selected. Every email automatically uses your project's branding (logo, colors, fonts).
Email Providers
Banata supports five email delivery providers out of the box:
- Resend — resend.com/api-keys
- SendGrid — app.sendgrid.com/settings/api_keys
- Amazon SES — AWS SES Documentation
- Mailgun — app.mailgun.com/settings/api_security
- Postmark — account.postmarkapp.com/servers
Setting Up a Provider
- Go to Emails > Providers in the dashboard.
- Click Enable on your preferred provider.
- Enter your API key in the field that appears.
- Click Save Key.
The provider you enable becomes your active provider automatically. Only one provider can be active at a time — enabling a new one switches delivery to it, and disabling the active provider sets it to none.
Send a Test Email
Once your provider is active, click the Send test email button at the top of the Providers page. Enter a recipient address and click Send. This dispatches a real email through your active provider so you can verify that delivery is working before going live.
Email Configuration
You control which types of transactional emails Banata sends. Each type can be toggled on or off independently from Emails > Configuration in the dashboard.
Authentication Emails
| Email Type | What It Does | Default |
|---|---|---|
| Magic Auth | Magic link and OTP authentication emails | Enabled |
| User Invitation | Invitation emails sent to new users | Enabled |
| Email Verification | Verification for new sign-ups and email changes | Enabled |
| Password Reset | Password reset request emails | Enabled |
Organization Emails
| Email Type | What It Does | Default |
|---|---|---|
| Critical Notifications | Important system notifications to organization admins | Enabled |
| Invitations | Organization membership invitation emails | Enabled |
Changes take effect immediately when you toggle an email type. If you disable a type, Banata will not send those emails even when your application triggers the corresponding auth flow.
Branded Email Delivery
All transactional emails — including organization invitation emails — are rendered using your project's branded template system. This means every email your users receive reflects your branding automatically:
- Logo displayed in the email header
- Primary color applied to buttons and links
- Background color for the email body
- Font family applied to all text
- Border radius on buttons and containers
- Dark mode support (optional)
You configure branding once in the dashboard under Branding, and every email inherits it. See Email Templates for template customization.
Sending Branded Emails from Code
In addition to the automatic emails Banata sends during auth flows, you can send branded emails programmatically. This works from any backend — Node.js, Bun, Hono, Express, Next.js, or any runtime that can make HTTP requests.
Using the API
Send a branded email with a single HTTP request. The email uses your configured provider and branding automatically:
// Works from any backend — Node, Bun, Deno, Hono, Express, etc.
const response = await fetch(
"https://auth.banata.dev/api/auth/banata/emails/send",
{
method: "POST",
headers: {
"Content-Type": "application/json",
"x-api-key": "sk_live_...",
},
body: JSON.stringify({
to: "user@example.com",
template: "welcome",
data: {
userName: "Jane Doe",
dashboardUrl: "https://app.example.com",
appName: "My App",
},
}),
}
);
const result = await response.json();
// { success: true } or { success: false, error: "..." }You can use any built-in template (verification, password-reset, magic-link, email-otp, invitation, welcome) or any custom template you've created by passing its slug.
Previewing Without Sending
Render a template to HTML without actually sending it — useful for testing or generating email content for your own delivery pipeline:
const response = await fetch(
"https://auth.banata.dev/api/auth/banata/emails/preview",
{
method: "POST",
headers: {
"Content-Type": "application/json",
"x-api-key": "sk_live_...",
},
body: JSON.stringify({
template: "welcome",
data: { userName: "Jane", dashboardUrl: "https://example.com", appName: "Acme" },
}),
}
);
const { subject, html, text } = await response.json();
// subject: "Welcome to Acme"
// html: full branded HTML email
// text: plain text versionOverriding Email Callbacks
If you need complete control over how specific email types are delivered (e.g., using your own email service instead of Banata's), you can provide callbacks in your auth configuration:
import { banataAuth } from "@banata-auth/convex";
export const auth = banataAuth({
email: {
// Override invitation emails with your own delivery
sendInvitationEmail: async ({ to, data }) => {
await myEmailService.send({
to,
subject: `You're invited to ${data.organizationName}`,
html: renderMyCustomTemplate(data),
});
},
},
});When you provide a callback, Banata uses it instead of the built-in branded template. If you don't provide a callback, Banata handles everything automatically.
Email Events
You can monitor email delivery from the dashboard under Emails > Events. This page shows a real-time feed of email activity including deliveries, verification sends, magic link dispatches, password resets, and invitation emails.
Each event shows the action type, the recipient address, and when it occurred.
Note: Events appear once you have a provider configured and your auth flows begin sending transactional emails. If no events have been recorded yet, you will see an empty state with a message confirming that events will appear once emails start flowing.
SDK Usage
You can also manage email provider configuration programmatically through the Banata SDK:
import {
getEmailProviderConfig,
saveEmailProviderConfig,
} from "@/lib/dashboard-api";
// Get current provider configuration
const providers = await getEmailProviderConfig();
console.log(providers.activeProvider); // "resend"
// Switch to SendGrid
await saveEmailProviderConfig({
providers: { sendgrid: { enabled: true, apiKey: "SG.xxx" } },
activeProvider: "sendgrid",
});For toggling email types in code:
import { getEmailConfig, toggleEmail } from "@/lib/dashboard-api";
// List all email toggle states
const emails = await getEmailConfig();
// Disable magic link emails
await toggleEmail("magic-auth", false);What's Next
- Email Templates — Customize the content and branding of the emails Banata sends
- Invitations — Invitation lifecycle and email delivery