> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kleap.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Email Integration

> Send emails from your app

Kleap builds **Astro static sites**, so there are two very different email needs, and they work in very different ways:

* **Form notifications** — built in. When someone submits a KleapForm, you (and optionally the respondent) get emailed automatically. No external service, no setup.
* **Custom / transactional email** — sending your own emails (welcome, password reset, order confirmation, newsletters). A static site has no server to send these, so it requires an external email provider called from a backend or serverless function. This is an advanced setup, not a one-click toggle.

## Form Notifications (Built In)

The simplest way to "get an email when something happens" is a **KleapForm**. Every form submission is:

* Stored in your dashboard (Forms → responses)
* Emailed to the site owner automatically

On the **Pro** plan you also get:

* **Respondent auto-reply** — automatically send a confirmation email back to the person who submitted the form
* **Webhooks** — POST each submission to any external URL (Zapier, Make, your own endpoint) to trigger further automation

Just ask the AI:

```
"Add a contact form that emails me when someone submits"
```

This covers most "email on submission" use cases — contact forms, lead capture, booking requests — with zero configuration.

## Custom / Transactional Email (Advanced)

If you need to send your own emails — welcome emails, password resets, order confirmations, newsletters — you need an external email provider. Because a Kleap site is **static** (no server runtime), the email-sending code has to run on a backend or serverless function you host separately, and your site calls it.

Be realistic: this is a developer task, not a setting inside Kleap.

### Email Services

You'll use an external email service to do the actual sending. When choosing one, compare on:

| Consideration            | What to look for                                |
| ------------------------ | ----------------------------------------------- |
| **Developer experience** | A simple API and clear docs                     |
| **Deliverability**       | A strong transactional-email reputation         |
| **Volume & pricing**     | A free tier and rates that fit your send volume |
| **Domain setup**         | Support for SPF, DKIM, and DMARC verification   |

### How It Works

1. Sign up with an external email service and get an API key.
2. Deploy a small serverless function (Cloudflare Worker, Vercel/Netlify function, etc.) that calls the provider's API. Your API key stays on the server — never ship it in the static site, where it would be publicly visible.
3. Call that function from your site (for example, from a form handler).

### Example Serverless Function

```typescript theme={null}
// A serverless function you host separately (e.g. Cloudflare Worker /
// Vercel / Netlify function) — NOT part of the static Astro site.
// It calls your chosen email service's HTTP API. The API key stays
// here on the server, never in the static site.
export async function POST(request: Request) {
  const { to, subject, html } = await request.json();

  const res = await fetch('https://api.your-email-service.com/emails', {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${process.env.EMAIL_API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ from: 'hello@yourdomain.com', to, subject, html }),
  });

  if (!res.ok) {
    return Response.json({ error: await res.text() }, { status: 500 });
  }

  return Response.json(await res.json());
}
```

### Verify Your Domain

For custom from addresses (`hello@yourdomain.com`), verify your domain with the provider and set up SPF, DKIM, and DMARC records. This is what keeps your email out of the spam folder.

## Common Email Types

Example prompts once you have an email backend wired up:

### Welcome Email

```
"Send a welcome email when a user signs up with their name
and a link to get started"
```

### Password Reset

```
"Add forgot password functionality that sends a reset link via email"
```

### Order Confirmation

```
"Send an order confirmation email with order details when a
purchase is completed"
```

### Newsletter

```
"Add newsletter signup that stores emails in Kleap Database
and can send bulk emails"
```

## Email Templates

### HTML Email

```typescript theme={null}
const emailHtml = `
  <div style="font-family: sans-serif; max-width: 600px; margin: 0 auto;">
    <h1 style="color: #333;">Welcome, ${name}!</h1>
    <p>Thanks for signing up. Here's how to get started:</p>
    <a href="${appUrl}/dashboard"
       style="background: #0070f3; color: white; padding: 12px 24px;
              text-decoration: none; border-radius: 6px;">
      Go to Dashboard
    </a>
  </div>
`;
```

### React Email Templates

For complex emails, use React Email:

```
"Install @react-email/components and create a reusable
welcome email template"
```

```typescript theme={null}
import { Html, Button, Text } from '@react-email/components';

export function WelcomeEmail({ name, dashboardUrl }) {
  return (
    <Html>
      <Text>Welcome, {name}!</Text>
      <Button href={dashboardUrl}>Go to Dashboard</Button>
    </Html>
  );
}
```

## Email Best Practices

### Avoid Spam Filters

<CardGroup cols={2}>
  <Card title="Use verified domain" icon="check">
    Set up SPF, DKIM, and DMARC
  </Card>

  <Card title="Clear from address" icon="envelope">
    Use recognizable sender name
  </Card>

  <Card title="Meaningful subject" icon="heading">
    Avoid spam trigger words
  </Card>

  <Card title="Include unsubscribe" icon="link">
    Required for marketing emails
  </Card>
</CardGroup>

### Rate Limiting

Don't send too many emails too fast:

```typescript theme={null}
// Simple rate limiting
const lastSent = await getLastEmailTime(userId);
if (Date.now() - lastSent < 60000) {
  throw new Error('Please wait before sending another email');
}
```

### Error Handling

```typescript theme={null}
try {
  await sendEmail({ to, subject, html });
} catch (error) {
  console.error('Email failed:', error);
  // Log to database for retry
  await logFailedEmail({ to, subject, error });
}
```

## Email with Queues

For high-volume or reliable email, queue messages instead of sending them inline.

### Queue Emails in Database

Store pending emails in **Kleap Database**:

```sql theme={null}
CREATE TABLE email_queue (
  id uuid PRIMARY KEY,
  to_email text,
  subject text,
  html text,
  status text DEFAULT 'pending',
  created_at timestamptz DEFAULT now()
);
```

Then process the queue from your serverless backend on a schedule (a cron job or scheduled function), sending each pending row and marking it sent.

## Testing Emails

### Development

Use your email service's test or sandbox mode, or a dedicated email-testing
tool that captures messages instead of delivering them (many provide a fake
SMTP inbox for local testing).

### Check Rendering

Preview how your email looks across different email clients with an
email-rendering tool before sending to real recipients.

## Troubleshooting

<AccordionGroup>
  <Accordion title="Emails not sending">
    * Check API key is correct
    * Verify it's set on your serverless backend
    * Check the provider's dashboard for errors
    * Verify from address is authorized
  </Accordion>

  <Accordion title="Emails going to spam">
    * Set up domain verification (SPF, DKIM, DMARC)
    * Check email content for spam triggers
    * Use a reputable email service
    * Add proper unsubscribe link
  </Accordion>

  <Accordion title="Rate limited">
    * Check your service's rate limits
    * Implement queuing for bulk sends
    * Upgrade plan if needed
  </Accordion>
</AccordionGroup>

<Card title="Kleap Database" icon="database" href="/features/forms-data">
  Store form responses, subscribers, and email logs
</Card>
