Local development
Run the API and dashboard on your machine.
You need Node 20 or newer, pnpm, a Supabase project and an AWS account.
git clone <your repository URL> sesamesend && cd sesamesend
pnpm install
cp .env.example .envFill in .env as you go; every variable is documented in that file. Then:
-
Create the Supabase project, apply the schema. See Supabase.
-
Create the AWS resources. See AWS setup.
-
Set
UNSUBSCRIBE_SECRET(openssl rand -base64 32 | tr -d '\n'),PUBLIC_BASE_URL(http://localhost:3000) andDASHBOARD_LOGIN_FROM. -
Create your first team and key:
node --env-file=.env scripts/bootstrap.mjs "My team" you@example.comThis writes
OPENSEND_API_KEYandCRON_SECRETto.envand never prints the key. It also makes you the team owner, so you can sign in to the dashboard. -
Run it:
pnpm devOpen http://localhost:3000/login. Only invited addresses get a sign-in link.
Background jobs
Scheduled sends, webhook delivery, broadcasts, automations, SES events and inbound mail run from six /internal/* endpoints. Locally, run the cron runner in a second terminal:
node --env-file=.env scripts/cron-runner.mjsWithout it, scheduled mail and webhooks sit still. See Vercel and background jobs.
Test without sending
- Simulator addresses at
resend.dev(delivered,bounced,complained,suppressed) are answered locally. pnpm check:offlineruns the offline checks: no database, AWS or email needed.RESEND_BASE_URL=http://localhost:3000 TEST_TO=you@example.com node --env-file=.env scripts/compat-send.mjssends real mail through the official SDK. Point it at a test Supabase project, not production.
Webhooks to localhost
Webhook endpoints must be https URLs. By default webhooks cannot reach private IP addresses. For a receiver on your own network, set OPENSEND_WEBHOOK_ALLOW_PRIVATE=1. It is for development and is ignored in production.