/resend
Emulated Resend email API for local development and testing. Use when the user needs to send emails locally, test transactional email flows, implement magic link or verification code auth, inspect sent emails, manage domains/contacts/API keys, or work with the Resend API without
$ npx -y skills add vercel-labs/emulate --skill resend --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/resend
Context preview
The summary Claude sees to decide when to auto-load this skill.
Emulated Resend email API for local development and testing. Use when the user needs to send emails locally, test transactional email flows, implement magic link or verification code auth, inspect sent emails, manage domains/contacts/API keys, or work with the Resend API without
SKILL.md
resend.SKILL.mdname: resend
description: Emulated Resend email API for local development and testing. Use when the user needs to send emails locally, test transactional email flows, implement magic link or verification code auth, inspect sent emails, manage domains/contacts/API keys, or work with the Resend API without sending real emails. Triggers include "Resend API", "emulate Resend", "send email locally", "test email", "magic link", "verification email", "email inbox", "RESEND_BASE_URL", or any task requiring a local email API.
allowed-tools: Bash(npx emulate:*), Bash(emulate:*), Bash(curl:*)
Resend Email API Emulator
Fully stateful Resend API emulation. Emails, domains, API keys, audiences, and contacts persist in memory. Sent emails are captured and viewable through the inbox UI or the REST API.
No real emails are sent. Every call to `POST /emails` stores the message locally so you can inspect it programmatically or in the browser.
Start
# Resend only
npx emulate --service resend
# Default port (when run alone)
# http://localhost:4000
Or programmatically:
import { createEmulator } from 'emulate'
const resend = await createEmulator({ service: 'resend', port: 4000 })
// resend.url === 'http://localhost:4000'Auth
Pass tokens as `Authorization: Bearer <token>`. Any `re_` prefixed token is accepted.
curl http://localhost:4000/emails \
-H "Authorization: Bearer re_test_key"
When no token is provided, requests fall back to the default user.
Pointing Your App at the Emulator
Environment Variable (Resend SDK)
The official Resend Node.js SDK reads `RESEND_BASE_URL` at module load time. Set it to the emulator URL and the SDK works without any code changes:
RESEND_BASE_URL=http://localhost:4000
import { Resend } from 'resend'
// No baseUrl argument needed; the SDK reads RESEND_BASE_URL automatically.
const resend = new Resend('re_test_key')
await resend.emails.send({
from: 'hello@example.com',
to: 'user@example.com',
subject: 'Hello',
html: '<p>It works!</p>',
})Embedded in Next.js (adapter-next)
When using `@emulators/adapter-next`, the emulator runs inside your Next.js app at `/emulate/resend`. Set `RESEND_BASE_URL` via `next.config.ts`:
// next.config.ts
import { withEmulate } from '@emulators/adapter-next'
export default withEmulate({
env: {
RESEND_BASE_URL: `http://localhost:${process.env.PORT ?? '3000'}/emulate/resend`,
},
})// app/emulate/[...path]/route.ts
import { createEmulateHandler } from '@emulators/adapter-next'
import * as resend from '@emulators/resend'
export const { GET, POST, PUT, PATCH, DELETE } = createEmulateHandler({
services: {
resend: {
emulator: resend,
seed: {
domains: [{ name: 'example.com' }],
},
},
},
})Direct fetch
If you cannot use the SDK or env var, call the emulator directly:
await fetch('http://localhost:4000/emails', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer re_test_key',
},
body: JSON.stringify({
from: 'hello@example.com',
to: 'user@example.com',
subject: 'Hello',
html: '<p>It works!</p>',
}),
})Seed Config
resend:
domains:
- name: example.com
region: us-east-1
contacts:
- email: test@example.com
first_name: Test
last_name: User
audience: DefaultRetrieving Sent Emails
This is the key differentiator of the emulator: every email sent via `POST /emails` is stored and queryable.
Inbox UI
Browse sent emails in the browser:
http://localhost:4000/inbox
REST API
# List all sent emails
curl http://localhost:4000/emails \
-H "Authorization: Bearer re_test_key"
# Get a single email by ID
curl http://localhost:4000/emails/<id> \
-H "Authorization: Bearer re_test_key"
Extracting Data from Emails (tests, agents)
Useful for completing magic link, verification code, or password reset flows programmatically:
# Get the latest email ID
EMAIL_ID=$(curl -s http://localhost:4000/emails \
-H "Authorization: Bearer re_test_key" | jq -r '.data[0].id')
# Extract a 6-digit code from the HTML body
CODE=$(curl -s http://localhost:4000/emails/$EMAIL_ID \
-H "Authorization: Bearer re_test_key" | jq -r '.html' | grep -oE '[0-9]{6}')
echo "Verification code: $CODE"API Endpoints
Emails
# Send an email
curl -X POST http://localhost:4000/emails \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"from": "hello@example.com", "to": "user@example.com", "subject": "Hello", "html": "<p>Hi</p>"}'
# Send batch (up to 100)
curl -X POST http://localhost:4000/emails/batch \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '[{"from": "a@example.com", "to": "b@example.com", "subject": "One", "html": "<p>1</p>"}]'
# List all emails
curl http://localhost:4000/emails \
-H "Authorization: Bearer $TOKEN"
# Get email by ID
curl http://localhost:4000/emails/<id> \
-H "Authorization: Bearer $TOKEN"
# Cancel a scheduled email
curl -X POST http://localhost:4000/emails/<id>/cancel \
-H "Authorization: Bearer $TOKEN"Supported fields: `from`, `to`, `subject`, `html`, `text`, `cc`, `bcc`, `reply_to`, `headers`, `tags`, `scheduled_at`.
Domains
# Create domain
curl -X POST http://localhost:4000/domains \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "example.com", "region": "us-east-1"}'
# List domains
curl http://localhost:4000/domains \
-H "Authorization: Bearer $TOKEN"
# Get domain
curl http://localhost:4000/domains/<id> \
-H "Authorization: Bearer $TOKEN"
# Verify domain (instantly marks all records as verified)
curl -X POST http://localhost:4000/domains/<id>/verify \
-H "Authorization: Bearer $TOKEN"
# Delete domaiRead more
name: resend description: Emulated Resend email API for local development and testing. Use when the user needs to send emails locally, test transactional email flows, implement magic link or verification code auth, inspect sent emails, manage domains/contacts/API keys, or work with the Resend API without sending real emails. Triggers include "Resend API", "emulate Resend", "send email locally", "test email", "magic link", "verification email", "email inbox", "RESEND_BASE_URL", or any task requiring a local email API. allowed-tools: Bash(npx emulate:*), Bash(emulate:*), Bash(curl:*)
Resend Email API Emulator
Fully stateful Resend API emulation. Emails, domains, API keys, audiences, and contacts persist in memory. Sent emails are captured and viewable through the inbox UI or the REST API.
No real emails are sent. Every call to `POST /emails` stores the message locally so you can inspect it programmatically or in the browser.
Start
# Resend only npx emulate --service resend # Default port (when run alone) # http://localhost:4000
Or programmatically:
import { createEmulator } from 'emulate'
const resend = await createEmulator({ service: 'resend', port: 4000 })
// resend.url === 'http://localhost:4000'Auth
Pass tokens as `Authorization: Bearer <token>`. Any `re_` prefixed token is accepted.
curl http://localhost:4000/emails \ -H "Authorization: Bearer re_test_key"
When no token is provided, requests fall back to the default user.
Pointing Your App at the Emulator
Environment Variable (Resend SDK)
The official Resend Node.js SDK reads `RESEND_BASE_URL` at module load time. Set it to the emulator URL and the SDK works without any code changes:
RESEND_BASE_URL=http://localhost:4000
import { Resend } from 'resend'
// No baseUrl argument needed; the SDK reads RESEND_BASE_URL automatically.
const resend = new Resend('re_test_key')
await resend.emails.send({
from: 'hello@example.com',
to: 'user@example.com',
subject: 'Hello',
html: '<p>It works!</p>',
})Embedded in Next.js (adapter-next)
When using `@emulators/adapter-next`, the emulator runs inside your Next.js app at `/emulate/resend`. Set `RESEND_BASE_URL` via `next.config.ts`:
// next.config.ts
import { withEmulate } from '@emulators/adapter-next'
export default withEmulate({
env: {
RESEND_BASE_URL: `http://localhost:${process.env.PORT ?? '3000'}/emulate/resend`,
},
})// app/emulate/[...path]/route.ts
import { createEmulateHandler } from '@emulators/adapter-next'
import * as resend from '@emulators/resend'
export const { GET, POST, PUT, PATCH, DELETE } = createEmulateHandler({
services: {
resend: {
emulator: resend,
seed: {
domains: [{ name: 'example.com' }],
},
},
},
})Direct fetch
If you cannot use the SDK or env var, call the emulator directly:
await fetch('http://localhost:4000/emails', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer re_test_key',
},
body: JSON.stringify({
from: 'hello@example.com',
to: 'user@example.com',
subject: 'Hello',
html: '<p>It works!</p>',
}),
})Seed Config
resend:
domains:
- name: example.com
region: us-east-1
contacts:
- email: test@example.com
first_name: Test
last_name: User
audience: DefaultRetrieving Sent Emails
This is the key differentiator of the emulator: every email sent via `POST /emails` is stored and queryable.
Inbox UI
Browse sent emails in the browser:
http://localhost:4000/inbox
REST API
# List all sent emails curl http://localhost:4000/emails \ -H "Authorization: Bearer re_test_key" # Get a single email by ID curl http://localhost:4000/emails/<id> \ -H "Authorization: Bearer re_test_key"
Extracting Data from Emails (tests, agents)
Useful for completing magic link, verification code, or password reset flows programmatically:
# Get the latest email ID
EMAIL_ID=$(curl -s http://localhost:4000/emails \
-H "Authorization: Bearer re_test_key" | jq -r '.data[0].id')
# Extract a 6-digit code from the HTML body
CODE=$(curl -s http://localhost:4000/emails/$EMAIL_ID \
-H "Authorization: Bearer re_test_key" | jq -r '.html' | grep -oE '[0-9]{6}')
echo "Verification code: $CODE"API Endpoints
Emails
# Send an email
curl -X POST http://localhost:4000/emails \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"from": "hello@example.com", "to": "user@example.com", "subject": "Hello", "html": "<p>Hi</p>"}'
# Send batch (up to 100)
curl -X POST http://localhost:4000/emails/batch \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '[{"from": "a@example.com", "to": "b@example.com", "subject": "One", "html": "<p>1</p>"}]'
# List all emails
curl http://localhost:4000/emails \
-H "Authorization: Bearer $TOKEN"
# Get email by ID
curl http://localhost:4000/emails/<id> \
-H "Authorization: Bearer $TOKEN"
# Cancel a scheduled email
curl -X POST http://localhost:4000/emails/<id>/cancel \
-H "Authorization: Bearer $TOKEN"Supported fields: `from`, `to`, `subject`, `html`, `text`, `cc`, `bcc`, `reply_to`, `headers`, `tags`, `scheduled_at`.
Domains
# Create domain
curl -X POST http://localhost:4000/domains \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "example.com", "region": "us-east-1"}'
# List domains
curl http://localhost:4000/domains \
-H "Authorization: Bearer $TOKEN"
# Get domain
curl http://localhost:4000/domains/<id> \
-H "Authorization: Bearer $TOKEN"
# Verify domain (instantly marks all records as verified)
curl -X POST http://localhost:4000/domains/<id>/verify \
-H "Authorization: Bearer $TOKEN"
# Delete domaiLocal drop-in replacement services for CI and no-network sandboxes. Fully stateful, production-fidelity API emulation. Not mocks.
Repo: vercel-labs/emulate
Other skills on emulate.
- /apple
Emulated Sign in with Apple / Apple OIDC for local development and testing. Use when the user needs to test Apple sign-in locally, emulate Apple OIDC discovery, handle Apple token exchange, configure Apple OAuth clients, or work with Apple userinfo without hitting real Apple
Open skill - /aws
Emulated AWS cloud services (S3, SQS, IAM, STS) for local development and testing. Use when the user needs to interact with AWS API endpoints locally, test S3 bucket and object operations, emulate SQS queues and messages, manage IAM users/roles/access keys, test STS assume role,
Open skill - /emulate
Local drop-in API emulator for Vercel, GitHub, Google, Slack, Apple, Microsoft, AWS, Linear, and other developer APIs. Use when the user needs to start emulated services, configure seed data, write tests against local APIs, set up CI without network access, or work with the
Open skill - /github
Emulated GitHub REST API for local development and testing. Use when the user needs to interact with GitHub API endpoints locally, test GitHub integrations, emulate repos/issues/PRs, set up GitHub OAuth flows, configure GitHub Apps, test webhooks, or work with actions/checks
Open skill - /google
Emulated Google OAuth 2.0, OpenID Connect, Gmail, Calendar, and Drive for local development and testing. Use when the user needs to test Google sign-in locally, emulate OIDC discovery, handle Google token exchange, configure Google OAuth clients, work with Gmail
Open skill - /linear
Emulated Linear GraphQL API for local development and testing. Use when the user needs to test Linear integrations locally, emulate Linear issues, comments, teams, workflow states, OAuth apps, webhooks, agent sessions, or work with the Linear API without hitting the real Linear
Open skill

