Risu Mail
API documentation
HTTP APIs live on the same host as the app. Use the guides below to authenticate, queue mail, and send OTPs.
Introduction
Base URL for this deployment:
https://risumail.vercel.app- Create secret keys in Dashboard → Mail API.
- Queued mail uses the Mail API; OTP routes send over SMTP in the request.
- Use the interactive studio at the bottom to copy snippets or run a test send.
Get started in 60 seconds
- 1
Create an API key
In the dashboard, create a key with send permission.
- 2
Send your first email
Replace
YOUR_API_KEYand run: - 3
Done
You should get
QUEUEDin the JSON response. Track delivery in Logs.
curl -X POST "https://risumail.vercel.app/api/v1/emails" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"to":"hello@example.com","subject":"Hello from Risu Mail","text":"Your first email is queued."}'Mail API
Queue-based sending for templates and transactional mail. Workers deliver asynchronously.
- ●Mail API —
POST /api/v1/emailsandPOST /api/v1/templates/sendreturn queued status. - ●OTP (browser / instant) — direct SMTP in the same HTTP request; not the template queue.
Advanced: OTP paths and dashboards
- Server OTP —
POST /api/v1/backend-otp/senduses your secret key only. See Server OTP API. - Browser OTP —
/api/v1/instant-otp/*withrisu_otp_…or secret key; CORS rules apply. Dashboard → OTP API.
Queue an email
Headers: Content-Type: application/json
- to — one email or array (required).
- subject — required, max 998 characters.
- At least one of: html, text, templateId, or imageUrl.
- templateId — optional; bodies from template if html/text omitted.
- vars — replaces
{{key}}placeholders (string / number / boolean). - imageUrl — optional https URL for image-style messages.
Success: 200 with { "success": true, "data": { "id": "<id>", "status": "QUEUED" } }
Send from template (queued)
Same queued pipeline as POST /api/v1/emails. Typical body: to, templateId, optional vars, overrides, and optional senderEmailId.
List sends
Paginated list for the authenticated user. limit capped at 100.
Hosted forms
- GET — hosted UI (iframe or direct link).
- POST — JSON or
multipart/form-data; responses includesubmissionId,saved,emailQueued, optionalqueuedEmailId,redirectUrl.
OTP API
Instant SMTP delivery; codes are stored hashed — the response does not include the OTP.
Send email OTP
Legacy alias: POST https://risumail.vercel.app/api/v1/otp/send
- email (required) — recipient.
- Optional: from, subject, verificationLine, otpDigits, expiresInSeconds.
Success: 200 with sessionId, expiresAt, to, sent. Counts toward monthly quota.
curl -X POST "https://risumail.vercel.app/api/v1/instant-otp/send" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"email":"user@example.com"}'Verify OTP
Legacy: POST https://risumail.vercel.app/api/v1/otp/verify
Body: sessionId, email, code.
Errors: INVALID_CODE, EXPIRED, LOCKED, NOT_FOUND.
curl -X POST "https://risumail.vercel.app/api/v1/instant-otp/verify" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"sessionId":"<sessionId>","email":"user@example.com","code":"123456"}'List verified OTP sessions
Requires both Authorization: Bearer risu_otp_… and X-Otp-Secret: risu_otp_sec_…. Same CORS and IP rules as send/verify. Legacy: GET …/api/v1/otp/verifications
Server OTP API (secret key only)
- Use
Authorization: Bearer risu_live_…withsendpermission. - Direct SMTP in the request — does not use the Mail API template queue.
- Optional env CORS via
API_CORS_ALLOWLIST.risu_otp_…tokens are rejected here.
Email verification by OTP
Separate OTP flow for verifying an email address.
- send — body:
email, optionalfrom,subject, etc. ReturnssessionId. - verify — body:
sessionId,email,code.
Authentication
- Secret API keys (
risu_live_…): Mail API routes and/api/v1/backend-otp/*useAuthorization: Bearer …withsendpermission. - Browser OTP —
/api/v1/instant-otp/sendand/verifyaccept the secret key or OTP client keys (risu_otp_…). Keys need at least one allowed hostname; browserOriginmust match. - 403 —
CORS_NOT_CONFIGURED(missing hostnames) orORIGIN_NOT_ALLOWED.
Examples
Build requests, switch languages, copy snippets, or run a live test against this deployment (paste a real API key).
Interactive API studio
Configure the request, copy multi-language snippets, or run a live test.
Checking session…·Authentication
Endpoint
Paste your secret key. Do not ship this to the browser in production.
Target email
One per line, or comma-separated.
Add at least one recipient in “Target email”.
Language
-- Add at least one recipient in “Target email”.
Error codes
Common responses when queueing mail:
VALIDATION_ERROR(400) — JSON or field rules.NOT_FOUND(404) — template not in your account.QUOTA_EXCEEDED/IMAGE_QUOTA_EXCEEDED(403) — plan limits.SMTP_NOT_CONFIGURED(503) — SMTP pool not configured.
Infrastructure (advanced)
The app uses MongoDB (DATABASE_URL). Outbound mail is queued as documents and sent by the embedded worker or npm run worker:email.