Before you start
- Create a free account and verify your domain in Dashboard → Domains.
- Create an API key in Dashboard → API keys.
- Add the key to your project’s server-side secrets or environment variables as
MAILUMI_API_KEY. Never paste it into the chat. - Copy a prompt, replace the part in [brackets] with what your app needs, and send it.
Send transactional email
Welcome emails, password resets, receipts and notifications from your own domain.
Add transactional email to this app using the Mailumi email API.
Read the reference first: https://mailumi.com/docs.md (complete docs in one file: https://mailumi.com/llms-full.txt).
Requirements:
1. Call Mailumi only from server-side code (an API route, server action or backend/edge function). Never use the API key in browser or mobile code.
2. Read the key from the environment variable MAILUMI_API_KEY and the sender from MAILUMI_FROM, for example "Acme <hello@yourdomain.com>". Add both to .env.example without real values.
3. Create one helper, sendEmail({ to, subject, html, text, idempotencyKey }). In a JavaScript or TypeScript project, install the official package (npm install mailumi) and call new Mailumi(process.env.MAILUMI_API_KEY).emails.send({ from, to, subject, html, text }, { idempotencyKey }), which resolves to { data, error }. In any other language, send POST https://mailumi.com/api/v1/emails with the headers "Authorization: Bearer <MAILUMI_API_KEY>", "Content-Type: application/json" and "Idempotency-Key", and a JSON body with from, to, subject, html and text, using the project's existing HTTP client.
4. Use a stable idempotency key for each logical email, such as "welcome-<userId>", so a retry never sends twice.
5. If the result has an error, throw it with its message. The mailumi package already retries 429 and 5xx with the same idempotency key; with plain HTTP, retry 429 and 503 up to 3 times with backoff, using the same key.
6. Use the helper for: [describe your emails, for example a welcome email after sign-up and a password reset email].
7. Write simple, inline-styled HTML that works in email clients, and a plain-text version of each email.
When you are done, tell me which environment variables to set and where.Track delivery with webhooks
Get delivered, bounced, complained, opened and clicked events in your app.
Add a webhook endpoint to this app that receives Mailumi email events.
Read the reference first: https://mailumi.com/docs.md (complete docs in one file: https://mailumi.com/llms-full.txt).
Requirements:
1. Create a server-side POST endpoint, for example /api/webhooks/mailumi.
2. Read the raw request body as text before parsing JSON; the signature covers the exact bytes.
3. Verify the Standard Webhooks signature. In a JavaScript or TypeScript project, use verifyWebhook({ payload: rawBody, headers: request.headers, secret: process.env.MAILUMI_WEBHOOK_SECRET }) from the official mailumi package; it resolves to { data: event, error }. Otherwise verify it yourself: the headers are webhook-id, webhook-timestamp and webhook-signature. The secret is in MAILUMI_WEBHOOK_SECRET and starts with "whsec_"; the HMAC key is the base64-decoded part after that prefix. Compute base64(HMAC-SHA256(key, webhook-id + "." + webhook-timestamp + "." + rawBody)) and compare it in constant time with each space-separated entry of webhook-signature, after its "v1," prefix. Respond 401 if none match or the timestamp is more than 5 minutes from now.
4. The event is JSON: { id, type, created_at, data }. data.email_id identifies the email and data.recipient the recipient the event is about.
5. Save each event id once (unique constraint) and ignore repeats; Mailumi retries failed deliveries with the same id.
6. Handle email.sent, email.delivered, email.delivery_delayed, email.bounced, email.complained, email.opened, email.clicked and email.failed: [describe what should happen, for example mark an address as invalid on email.bounced].
7. Respond 200 within 8 seconds and move slow work to a background job.
When you are done, tell me the endpoint URL to add in Mailumi under Dashboard → Webhooks.Receive incoming email
Turn email sent to your domain into tickets, replies or uploads.
Let this app receive incoming email through Mailumi.
Read the reference first: https://mailumi.com/docs.md (complete docs in one file: https://mailumi.com/llms-full.txt).
Requirements:
1. Create a server-side POST endpoint, for example /api/webhooks/mailumi-inbound.
2. Verify the Standard Webhooks signature before trusting anything: read the raw body as text, then check it with verifyWebhook from the official mailumi package in JavaScript or TypeScript, or in other languages check webhook-id, webhook-timestamp and webhook-signature with HMAC-SHA256 and the base64 part of MAILUMI_WEBHOOK_SECRET after "whsec_", exactly as the docs describe. Respond 401 if it does not match.
3. Handle events with type "email.received". data contains email_id, from, to, cc, reply_to, subject, text, html, message_id, spam and attachments.
4. Each attachment has filename, content_type, size and download_url. Download it from the server with the header "Authorization: Bearer <MAILUMI_API_KEY>" (a key with the email:read permission). Never send that URL or key to the browser.
5. Save each event id once and ignore repeats.
6. [Describe what to do with incoming email, for example create a support ticket or add the reply to a conversation.]
7. Respond 200 within 8 seconds; process large attachments in a background job.Switch from another provider
Move from Resend, SendGrid, Mailgun, Postmark or SMTP in one pass.
Replace this app's current email provider (for example Resend, SendGrid, Mailgun, Postmark or SMTP with Nodemailer) with the Mailumi email API.
Read the reference first: https://mailumi.com/docs.md (complete docs in one file: https://mailumi.com/llms-full.txt, migration guide: https://mailumi.com/migration).
Requirements:
1. Find every place that sends email and route it through one server-side helper, sendEmail({ to, subject, html, text, idempotencyKey }). In JavaScript or TypeScript, use the official mailumi package (npm install mailumi); its emails.send and batch.send match the Resend SDK and also return { data, error }. In other languages, call POST https://mailumi.com/api/v1/emails with "Authorization: Bearer <MAILUMI_API_KEY>".
2. Keep the same senders, subjects and templates. Map cc, bcc, reply_to, attachments (base64 content and filename), custom headers and tags to the Mailumi fields in the docs.
3. Send a stable Idempotency-Key per logical email and retry 429 and 503 with the same key.
4. Replace the old provider's webhooks with a Mailumi webhook endpoint that verifies the Standard Webhooks signature with MAILUMI_WEBHOOK_SECRET, and map the old event names to Mailumi's email.* events.
5. Remove the old provider's package and environment variables once nothing uses them, and update .env.example.
6. List anything that has no direct equivalent so I can decide what to do.
If the app sends through SMTP and I only want to change settings, keep the SMTP code and point it at Mailumi instead: host smtp.mailumi.com, port 465 with TLS or 587 with STARTTLS, username mailumi, password MAILUMI_API_KEY.Connect your editor with MCP
Add the Mailumi MCP server and your assistant can send a test email, check whether it was delivered and see which domains are verified, without leaving Cursor, Claude Code, VS Code or Codex. It works with your normal API key, so a key without email:send gives read-only access.
MAILUMI_API_KEY in your system environment and restart Cursor.{
"mcpServers": {
"mailumi": {
"url": "https://mailumi.com/mcp",
"headers": {
"Authorization": "Bearer ${env:MAILUMI_API_KEY}"
}
}
}
}claude mcp add --transport http mailumi https://mailumi.com/mcp \
--header "Authorization: Bearer $MAILUMI_API_KEY"{
"inputs": [
{
"type": "promptString",
"id": "mailumi-api-key",
"description": "Mailumi API key",
"password": true
}
],
"servers": {
"mailumi": {
"type": "http",
"url": "https://mailumi.com/mcp",
"headers": {
"Authorization": "Bearer ${input:mailumi-api-key}"
}
}
}
}[mcp_servers.mailumi]
url = "https://mailumi.com/mcp"
bearer_token_env_var = "MAILUMI_API_KEY"- Cursor: Add to Cursor in one click, or save the JSON in
~/.cursor/mcp.json. - Claude Code: run the command in your terminal.
- VS Code: save the JSON as
.vscode/mcp.json; VS Code asks for the key once and stores it securely. - Codex: add the lines to
~/.codex/config.toml.
Your assistant can use these tools: send_email, list_emails, get_email, reschedule_email, cancel_email, list_domains, get_documentation. Emails it sends count toward your plan and appear in Email activity, like any other email. Read the MCP reference.
Rules for your assistant
Save these rules in your project so every chat knows how Mailumi works: as AGENTS.md for Codex, Copilot and most agents, as CLAUDE.md for Claude Code, or as a Cursor rule.
# Mailumi email API
This project sends and receives email with Mailumi. Complete reference: https://mailumi.com/llms-full.txt
- Base URL: https://mailumi.com/api/v1. Authenticate with the header "Authorization: Bearer $MAILUMI_API_KEY". Call Mailumi only from server-side code; never expose the key to browsers or mobile apps.
- JavaScript and TypeScript: use the official package (npm install mailumi). const mailumi = new Mailumi(process.env.MAILUMI_API_KEY); const { data, error } = await mailumi.emails.send({ from, to, subject, html }, { idempotencyKey }). Methods never throw for API errors; they resolve to { data, error }. Verify webhooks with verifyWebhook({ payload: rawBody, headers, secret }).
- Send: POST /emails with JSON { from, to, subject, html and/or text } and optional cc, bcc, reply_to, attachments [{ filename, content (base64), content_type, content_id }], headers, tags [{ name, value }] and scheduled_at. The from domain must be verified in Mailumi.
- Batch: POST /emails/batch with an array of up to 100 emails (no attachments or scheduled_at). Templates: pass template_id and variables instead of subject and html.
- Software that only speaks SMTP: host smtp.mailumi.com, port 465 (TLS) or 587 (STARTTLS), username mailumi, password $MAILUMI_API_KEY.
- Always send an Idempotency-Key header that is stable for each logical email. Retry 429 and 503 with the same key.
- Errors are JSON { "error": "message", "code": "machine_readable_code" } with a 4xx or 5xx status. On 429, wait the seconds in the Retry-After header. OpenAPI description: https://mailumi.com/openapi.json
- Webhooks use the Standard Webhooks format. Verify webhook-signature ("v1," + base64 HMAC-SHA256 of webhook-id + "." + webhook-timestamp + "." + raw body) with the base64 part of MAILUMI_WEBHOOK_SECRET after "whsec_", in constant time. Reject timestamps older than 5 minutes and process each event id once.
- Events: email.sent, email.delivered, email.delivery_delayed, email.bounced, email.complained, email.opened, email.clicked, email.failed, email.unsubscribed, email.received.Docs your assistant can read
Paste one of these links into the chat, or add it as a docs source in your tool, for example with @Docs in Cursor.
- https://mailumi.com/llms-full.txt
The complete API reference, code examples, webhook checks and these prompts in one file. Best for AI tools.
- https://mailumi.com/docs.md
The API documentation as Markdown.
- https://mailumi.com/llms.txt
A short overview of Mailumi with links to every page.
Building with AI: common questions
- Can I use Mailumi with Lovable, Bolt, v0 or Replit?
- Yes. Mailumi is a plain HTTPS API, so any tool that writes backend code can use it. Store your API key in the project’s server-side secrets, for example a Supabase Edge Function secret in Lovable or Bolt, and let the prompt call Mailumi from that server code.
- Do I need to install an SDK?
- Only if you want one. JavaScript and TypeScript projects can use the official mailumi package (npm install mailumi): typed, without dependencies, with safe retries and webhook verification built in. In every other language one HTTPS request sends an email, so your assistant uses the HTTP client the project already has.
- Can my assistant send a test email and check that it arrived?
- Yes. Connect the Mailumi MCP server to Cursor, Claude Code, VS Code or Codex with your API key. Your assistant can then send a test email, read its delivery events and list your verified domains while it builds the integration.
- Is it safe to paste these prompts into an AI tool?
- Yes. The prompts contain no keys or account details. Your assistant reads the key from an environment variable that you set yourself, and every prompt tells it to keep the key out of browser code. Never paste your API key into a chat.
- What does my assistant need to know about Mailumi?
- Everything is in one file: llms-full.txt contains the complete API reference, code examples, webhook signature checks and these prompts. Add it to your tool’s docs, or save the rules file as AGENTS.md, CLAUDE.md or a Cursor rule so every chat knows Mailumi.