curl Quickstart

No SDK. No language runtime. Just curl and a Bearer token. Useful for shell scripts, cron jobs, CI tasks, language-agnostic integrations.

1. Get an API key

Generate one at /api-keys. Two types: ms_test_* (sandbox) and ms_live_* (production). Store in your shell:

terminal
export MAILSTORM_API_KEY="ms_test_..."

2. Send a single email

terminal
curl -X POST https://mailstorm.dev/v1/emails \
  -H "Authorization: Bearer $MAILSTORM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "onboarding@yourdomain.com",
    "to": "user@example.com",
    "subject": "Hello",
    "html": "<p>It works.</p>"
  }'

Response (success):

response
{"id":"39b79255069f04bcb5f9c94643c74e8f","status":"queued"}

3. Get an email by id

terminal
curl https://mailstorm.dev/v1/emails/$EMAIL_ID \
  -H "Authorization: Bearer $MAILSTORM_API_KEY"

Response includes both Resend-shape fields (object, last_event, to as array) and Mailstorm-native fields (status, ses_id, error, sent_at). Pick whichever shape your code expects.

4. Send a batch (Resend wire shape)

terminal
curl -X POST https://mailstorm.dev/v1/emails/batch \
  -H "Authorization: Bearer $MAILSTORM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '[
    {"from":"a@yourdomain.com","to":["x@b.c"],"subject":"1","html":"<p>1</p>"},
    {"from":"a@yourdomain.com","to":["y@b.c"],"subject":"2","html":"<p>2</p>"}
  ]'

5. Send a batch (Mailstorm-native wire shape)

terminal
curl -X POST https://mailstorm.dev/v1/batch \
  -H "Authorization: Bearer $MAILSTORM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "emails": [
      {"from":"a@yourdomain.com","to":"x@b.c","subject":"1","html":"<p>1</p>"},
      {"from":"a@yourdomain.com","to":"y@b.c","subject":"2","html":"<p>2</p>"}
    ]
  }'

6. Idempotency

terminal
curl -X POST https://mailstorm.dev/v1/emails \
  -H "Authorization: Bearer $MAILSTORM_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-12345" \
  -d '{...}'

Same key + same body within 24h returns the original response without re-sending.

7. Common errors

CodeBodyMeaning
401{"error":"invalid api key"}Key doesn't exist or was deleted
401{"error":"missing api key"}No Authorization header
401{"error":"account disabled — contact support"}Account paused (abuse trigger or manual)
403{"error":"domain X is not registered..."}FROM domain not verified for this account (live mode)
429{"error":"daily send cap reached..."}Tier or probation cap exceeded

What's next