{"_id":"@aks-builds/email-api","_rev":"5-3657add8e0fa8c8e81342c249e312a1c","name":"@aks-builds/email-api","dist-tags":{"latest":"0.4.0"},"versions":{"0.2.2":{"name":"@aks-builds/email-api","version":"0.2.2","license":"MIT","_id":"@aks-builds/email-api@0.2.2","maintainers":[{"name":"aks-builds","email":"its.aks@outlook.com"}],"homepage":"https://github.com/aks-builds/email-api#readme","bugs":{"url":"https://github.com/aks-builds/email-api/issues"},"bin":{"email-api":"bin/email-api.js"},"dist":{"shasum":"805b61fbcc472286cebaf7eb7a7b4aa7ec83735b","tarball":"https://registry.npmjs.org/@aks-builds/email-api/-/email-api-0.2.2.tgz","fileCount":45,"integrity":"sha512-TAErX5sutg94aGTHtvu2hWR6pj8OyGvuC0WOX87gsZUuX8p6etdm+uJoAAbHHOyNQ+osmzMMoXADip/FIWtsbA==","signatures":[{"sig":"MEQCIBgvKTY4X7HF1PCT8UnxUNegdwvJ03JOj4UW8DBg61ieAiBsIDFOUbwE409+EDd8GJfwTMaB5pDHj00jDBl8X52Wqw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aks-builds%2femail-api@0.2.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":80231},"type":"module","engines":{"node":">=22.5"},"gitHead":"a0b9bce12f34a958f04e973a9ca7d3b57340f63e","scripts":{"tui":"node bin/email-api.js tui","test":"node --test","server":"node bin/email-api.js server"},"_npmUser":{"name":"aks-builds","email":"its.aks@outlook.com"},"repository":{"url":"git+https://github.com/aks-builds/email-api.git","type":"git"},"_npmVersion":"10.9.8","description":"Self-hosted RESTful email service with TUI client","directories":{},"_nodeVersion":"22.22.3","dependencies":{"multer":"^1.4.5-lts.1","nanoid":"^5.0.7","blessed":"^0.1.81","express":"^4.19.2","node-cron":"^3.0.3","nodemailer":"^6.9.13"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/email-api_0.2.2_1781423295071_0.4306998218478735","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@aks-builds/email-api","version":"0.3.0","license":"MIT","_id":"@aks-builds/email-api@0.3.0","maintainers":[{"name":"aks-builds","email":"its.aks@outlook.com"}],"homepage":"https://github.com/aks-builds/email-api#readme","bugs":{"url":"https://github.com/aks-builds/email-api/issues"},"bin":{"email-api":"bin/email-api.js","email-send":"bin/email-send.js"},"dist":{"shasum":"24c8c0078c7701e81dc2b908b1a0617f77bd9013","tarball":"https://registry.npmjs.org/@aks-builds/email-api/-/email-api-0.3.0.tgz","fileCount":49,"integrity":"sha512-8SEXe+0zhSjjQJ1XSFmFvT+6cLTsS+g+ftjtUyjgIj16CawO9yNjA/zYrRVMEQsguLTlB1F8pXJHzxlzqh6dNw==","signatures":[{"sig":"MEYCIQCcF03sfGhDSiT5RU5snda3Uj6tExaiX8djuU5YdhOKhgIhALxG1mE0LufynACbfC6uLTVsaWJ+wqVd3/S4FQOMuql/","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aks-builds%2femail-api@0.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":103486},"type":"module","engines":{"node":">=22.5"},"gitHead":"9b5afdeadd654c75ef2bb62eda586beeaa40f4b2","scripts":{"tui":"node bin/email-api.js tui","test":"node --test","server":"node bin/email-api.js server"},"_npmUser":{"name":"aks-builds","email":"its.aks@outlook.com"},"repository":{"url":"git+https://github.com/aks-builds/email-api.git","type":"git"},"_npmVersion":"10.9.8","description":"Self-hosted RESTful email service with TUI client","directories":{},"_nodeVersion":"22.22.3","dependencies":{"multer":"^1.4.5-lts.1","nanoid":"^5.0.7","blessed":"^0.1.81","express":"^4.19.2","node-cron":"^3.0.3","nodemailer":"^6.9.13"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/email-api_0.3.0_1781441787659_0.7687599314198601","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"@aks-builds/email-api","version":"0.3.1","license":"MIT","_id":"@aks-builds/email-api@0.3.1","maintainers":[{"name":"aks-builds","email":"its.aks@outlook.com"}],"homepage":"https://github.com/aks-builds/email-api#readme","bugs":{"url":"https://github.com/aks-builds/email-api/issues"},"bin":{"email-api":"bin/email-api.js","email-send":"bin/email-send.js"},"dist":{"shasum":"c36ed3aadd47705e9f08ccd963f877e5a201c6cf","tarball":"https://registry.npmjs.org/@aks-builds/email-api/-/email-api-0.3.1.tgz","fileCount":50,"integrity":"sha512-OVLNHYe/Lsh3xMcM43lFJoU0WwVZZz/7y7Gx+dOWIHWK3bofyjJzIM8UVoGjRd1fexanhYkrqG9m82Cebdoidg==","signatures":[{"sig":"MEUCIACYoEaW8i/PETl5g2LW4Y/n4kFuOntJZ2G8crHEtTlFAiEA7nDQBwf6XrhCmNfnfIUliiWs8ITvHXOjjcHDTo5NZI0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aks-builds%2femail-api@0.3.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":112895},"type":"module","engines":{"node":">=22.5"},"gitHead":"7d21eef2f2bfa71aeb6261fbc19ec34dab49d128","scripts":{"tui":"node bin/email-api.js tui","test":"node --test","server":"node bin/email-api.js server"},"_npmUser":{"name":"aks-builds","email":"its.aks@outlook.com"},"repository":{"url":"git+https://github.com/aks-builds/email-api.git","type":"git"},"_npmVersion":"10.9.8","description":"Self-hosted RESTful email service with TUI client","directories":{},"_nodeVersion":"22.22.3","dependencies":{"multer":"^1.4.5-lts.1","nanoid":"^5.0.7","blessed":"^0.1.81","express":"^4.19.2","node-cron":"^3.0.3","nodemailer":"^6.9.13"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/email-api_0.3.1_1781443377489_0.6614036214346009","host":"s3://npm-registry-packages-npm-production"}},"0.3.2":{"name":"@aks-builds/email-api","version":"0.3.2","license":"MIT","_id":"@aks-builds/email-api@0.3.2","maintainers":[{"name":"aks-builds","email":"its.aks@outlook.com"}],"homepage":"https://github.com/aks-builds/email-api#readme","bugs":{"url":"https://github.com/aks-builds/email-api/issues"},"bin":{"email-api":"bin/email-api.js","email-send":"bin/email-send.js"},"dist":{"shasum":"179b7f1cfe644380ecc8f658094dd0df883cd796","tarball":"https://registry.npmjs.org/@aks-builds/email-api/-/email-api-0.3.2.tgz","fileCount":50,"integrity":"sha512-otsPG9q8bNPXMyOpi16PzMXzUeIYpv3T1M7X/ILKZM/Sqy6vE7aYxIjmdCOa7uH6YJ380CEKne0tAZ8YhBy15w==","signatures":[{"sig":"MEUCIQCjt5Is17ZzBGxTsC0+lyNbl0Q6WiZrrFfPHTK6SlsaJwIgE15plET8CEfMrix8wHFBLTkx8kUBk40vDtIlSFfgLZg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aks-builds%2femail-api@0.3.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":113046},"type":"module","engines":{"node":">=22.5"},"gitHead":"3c1811084788c122986382d1c35e59fe1536dd8d","scripts":{"tui":"node bin/email-api.js tui","test":"node --test","server":"node bin/email-api.js server"},"_npmUser":{"name":"aks-builds","email":"its.aks@outlook.com"},"repository":{"url":"git+https://github.com/aks-builds/email-api.git","type":"git"},"_npmVersion":"10.9.8","description":"Self-hosted RESTful email service with TUI client","directories":{},"_nodeVersion":"22.22.3","dependencies":{"multer":"^1.4.5-lts.1","nanoid":"^5.0.7","blessed":"^0.1.81","express":"^4.19.2","node-cron":"^3.0.3","nodemailer":"^6.9.13"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/email-api_0.3.2_1781514821815_0.6273224093466905","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@aks-builds/email-api","version":"0.4.0","description":"Self-hosted RESTful email service with TUI client","type":"module","engines":{"node":">=22.5"},"bin":{"email-api":"bin/email-api.js","email-send":"bin/email-send.js"},"scripts":{"server":"node bin/email-api.js server","tui":"node bin/email-api.js tui","test":"node --test"},"repository":{"type":"git","url":"git+https://github.com/aks-builds/email-api.git"},"bugs":{"url":"https://github.com/aks-builds/email-api/issues"},"homepage":"https://github.com/aks-builds/email-api#readme","license":"MIT","dependencies":{"blessed":"^0.1.81","express":"^4.19.2","multer":"^1.4.5-lts.1","nanoid":"^5.0.7","node-cron":"^3.0.3","nodemailer":"^6.9.13"},"_id":"@aks-builds/email-api@0.4.0","gitHead":"e7b5a6c5ce5672d8750d98d298422bb29bd90d77","_nodeVersion":"22.22.3","_npmVersion":"10.9.8","dist":{"integrity":"sha512-uNmrnrCtMUqLBBViQ67EseRxUugJymmws8ww1QVkjj4L6zfOqo9KvyA7NvrVy5UahBryhGXMR7Nrn0PQidG2+g==","shasum":"c38257ebc9f9d80bd7452def12f8b1311b6063ef","tarball":"https://registry.npmjs.org/@aks-builds/email-api/-/email-api-0.4.0.tgz","fileCount":52,"unpackedSize":166125,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aks-builds%2femail-api@0.4.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCth78fXh7D9cZM5u8YIrchWMlxiYkVDoYzQNv9JRmkYgIgHl1D6H6uP4D1SYt7ZMzG3VuumebOUVVaucBFqPRva70="}]},"_npmUser":{"name":"aks-builds","email":"its.aks@outlook.com"},"directories":{},"maintainers":[{"name":"aks-builds","email":"its.aks@outlook.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/email-api_0.4.0_1781529989218_0.027547087038355178"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-14T07:48:14.952Z","modified":"2026-06-15T13:26:29.653Z","0.2.2":"2026-06-14T07:48:15.209Z","0.3.0":"2026-06-14T12:56:27.806Z","0.3.1":"2026-06-14T13:22:57.645Z","0.3.2":"2026-06-15T09:13:41.961Z","0.4.0":"2026-06-15T13:26:29.354Z"},"bugs":{"url":"https://github.com/aks-builds/email-api/issues"},"license":"MIT","homepage":"https://github.com/aks-builds/email-api#readme","repository":{"type":"git","url":"git+https://github.com/aks-builds/email-api.git"},"description":"Self-hosted RESTful email service with TUI client","maintainers":[{"name":"aks-builds","email":"its.aks@outlook.com"}],"readme":"<div align=\"center\">\n\n# 📬 email-api\n\n**Your app shouldn't need to know anything about SMTP. It should just call a REST endpoint.**\n\n`email-api` is a self-hosted service that wraps Nodemailer behind a clean HTTP API — with attachments,\nCC/BCC, HTML bodies, per-sender templates, scheduled delivery, and automatic retry baked in.\nRun it once, call it from anywhere, and manage everything from a rich terminal dashboard.\n\n[![CI](https://github.com/aks-builds/email-api/actions/workflows/ci.yml/badge.svg)](https://github.com/aks-builds/email-api/actions/workflows/ci.yml)\n[![CodeQL](https://github.com/aks-builds/email-api/actions/workflows/codeql.yml/badge.svg)](https://github.com/aks-builds/email-api/actions/workflows/codeql.yml)\n[![npm version](https://img.shields.io/npm/v/@aks-builds/email-api.svg)](https://www.npmjs.com/package/@aks-builds/email-api)\n[![License MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n\n<br/>\n\n![37 tests passing across emails, keys, auth, scheduler, validator, and template modules](.github/media/demo.svg)\n\n<sub>☝️ 37 tests across REST routes, auth middleware, scheduler, validator, and template renderer. All green.</sub>\n\n</div>\n\n---\n\n## The problem it solves\n\nAdding email to a service means choosing an SDK, wiring credentials into every service that needs it,\nand reinventing retry logic each time. `email-api` pulls that concern out of your app entirely.\nEvery service in your stack calls one endpoint. Credentials live in one place. History is isolated per API key.\n\n---\n\n## Install\n\n```bash\nnpm install -g @aks-builds/email-api\n```\n\nRequires **Node.js ≥ 22.5** (uses the built-in `node:sqlite` module).\n\n---\n\n## `email-send` — quick send CLI\n\nOne command to send an email from your terminal. Catppuccin Mocha UI, Gmail REST API over HTTPS, attachments, multi-recipient, `$EDITOR` body input. Works in cmd.exe, PowerShell, and bash.\n\n![email-send compose flow — FROM, TO, SUBJECT, BODY via editor, ATTACHMENTS, CONFIRM, DELIVERED](.github/media/email-send-demo.svg)\n\n<sub>☝️ Real Catppuccin Mocha UI. Gmail credentials saved once to <code>~/.email-api/config.json</code> — every subsequent run goes straight to COMPOSE.</sub>\n\n```bash\n# Install once\nnpm install -g @aks-builds/email-api\n\n# Run anywhere — cmd.exe, PowerShell, or bash\nemail-send\n```\n\n---\n\n## Quickstart\n\n```bash\n# Start the server — generates an API key on first run\nemail-api server\n\n# ┌─────────────────────────────────────────────┐\n# │  email-api: API key generated (save this!)  │\n# │  a3f9c2...e81b                              │\n# │  Set EMAIL_API_KEY in .env to pin it        │\n# └─────────────────────────────────────────────┘\n# email-api server running on http://localhost:3000\n\n# Send an email\ncurl -X POST http://localhost:3000/emails \\\n  -H \"Authorization: Bearer <your-key>\" \\\n  -F \"to=alice@example.com\" \\\n  -F \"subject=Hello\" \\\n  -F \"text=World\"\n\n# Open the TUI dashboard (separate terminal)\nemail-api tui\n```\n\n---\n\n## REST API\n\nAll routes except `GET /health` require `Authorization: Bearer <key>`.\nAll error responses follow `{ \"error\": \"CODE\", \"message\": \"...\", \"statusCode\": N }`.\n\n### Emails\n\n```\nPOST   /emails          Send or schedule an email (multipart/form-data)\nGET    /emails          List history for this key (?status=&page=&limit=)\nGET    /emails/:id      Get a single email record + delivery status\nDELETE /emails/:id      Cancel a scheduled email (pending only)\n```\n\n**POST /emails fields:**\n\n| Field | Type | Required |\n|---|---|---|\n| `to` | string \\| comma-separated | yes |\n| `cc` | string \\| comma-separated | no |\n| `bcc` | string \\| comma-separated | no |\n| `subject` | string | yes |\n| `text` | string | at least one of text/html/template |\n| `html` | string | at least one of text/html/template |\n| `template` | string (template name) | no |\n| `templateVars` | JSON string | no |\n| `scheduledAt` | ISO 8601 datetime | no (omit = send immediately) |\n| `attachments` | File[] (multipart) | no — up to 10 × 25 MB |\n\n**Email status lifecycle:**\n\n```\npending → sending → sent\n                 ↘ failed      (after 3 retries: 30s → 2m → 10m)\n         → cancelled           (DELETE while pending)\n```\n\n### Keys\n\n```\nPOST   /keys            Create a named API key → returns raw key once\nGET    /keys            List active keys (names + IDs, never raw values)\nDELETE /keys/:id        Revoke a key\n```\n\n### Health\n\n```\nGET    /health          Server status, active key count (no auth required)\n```\n\n---\n\n## Configuration\n\nSet in `.env` or environment variables. Copy `.env.example` to get started.\n\n```bash\n# Auto-generated on first run if absent\nEMAIL_API_KEY=\n\nSERVER_PORT=3000\n\n# SMTP — defaults to Brevo free tier (300 emails/day)\nSMTP_HOST=smtp-relay.brevo.com\nSMTP_PORT=587\nSMTP_USER=your@email.com\nSMTP_PASS=your-brevo-smtp-key\n# RFC 5322 format: \"Display Name <address@domain>\" or just \"address@domain\"\nSMTP_FROM=Your Name <your@email.com>\n\n# Set to true to keep attachment files on disk after successful send\nKEEP_ATTACHMENTS=false\n# Runtime data directory (SQLite DB, config.json, attachments, templates)\nDATA_DIR=./data\n```\n\nAny SMTP provider works — change `SMTP_HOST/PORT/USER/PASS` to point at Gmail, AWS SES, Mailgun,\nResend, or a local relay.\n\n---\n\n## Features\n\n### HTML emails\nPass `html` alongside `text` for a `multipart/alternative` message. If only `html` is provided, a plain-text fallback is auto-stripped.\n\n### Attachments\nUp to 10 files, 25 MB each, 50 MB total per email. Stored under `./data/attachments/<emailId>/` and cleaned up after successful delivery (unless `KEEP_ATTACHMENTS=true`).\n\n### Templates\nStore templates as `./data/templates/<name>.html` and/or `<name>.txt`. Reference them with `template=welcome` and pass variables as `templateVars={\"name\":\"Alice\"}`. Variables use `{{varName}}` syntax.\n\n```bash\ncurl -X POST http://localhost:3000/emails \\\n  -H \"Authorization: Bearer <key>\" \\\n  -F \"to=alice@example.com\" \\\n  -F \"subject=Welcome!\" \\\n  -F \"template=welcome\" \\\n  -F 'templateVars={\"name\":\"Alice\",\"link\":\"https://example.com/verify\"}'\n```\n\n### Scheduled sending\nPass `scheduledAt` as an ISO 8601 datetime. The scheduler picks it up within 30 seconds.\n\n```bash\n# Schedule for tomorrow morning\n-F \"scheduledAt=2026-06-15T09:00:00Z\"\n```\n\n### Retry on failure\nTransient SMTP errors are retried up to 3 times with exponential backoff (30s → 2m → 10m). Permanent errors (5xx SMTP codes) fail immediately. Failure details are captured in `last_error` and surfaced in the TUI.\n\n### Per-key isolation\nEvery API key sees only its own email history. Create one key per service, rotate independently, revoke without affecting others.\n\n---\n\n## TUI Dashboard\n\nPress `S` to compose, `L` for logs, `C` for config, `H` for the dashboard, `R` to refresh, `Q` to quit.\n\n```\n┌─ email-api ──────────────────────────────────────────────────────────────┐\n│  ✔ 47 sent  ✘ 2 failed  ⟳ 3 pending  ⏰ 5 scheduled  ● connected :3000  │\n├─ Recent Emails ────────────────────────────┬─ Live Log ──────────────────┤\n│  ✔ alice@acme.com  Quarterly Report        │ 14:22:01 sent → alice       │\n│  ✔ bob@acme.com    Invoice #4421           │ 14:21:44 sent → bob         │\n│  ✘ charlie@ex.com  Welcome email [timeout] │ 14:20:11 failed → charlie   │\n│  ⏰ team@acme.com   Weekly Digest [9am]    │ 14:20:11 retry scheduled    │\n│  ⟳ dave@acme.com   Password Reset [2/3]   │ 14:19:58 scheduler tick     │\n├────────────────────────────────────────────┴─────────────────────────────┤\n│  S Compose  L Logs  C Config  H Dashboard  R Refresh  Q Quit             │\n└──────────────────────────────────────────────────────────────────────────┘\n```\n\n---\n\n## Multi-key example\n\n```bash\n# Create a key for your notifications service\ncurl -X POST http://localhost:3000/keys \\\n  -H \"Authorization: Bearer <admin-key>\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"name\":\"notifications-svc\"}'\n# → { \"id\": \"abc123\", \"name\": \"notifications-svc\", \"key\": \"...\" }\n\n# That service uses its own key — isolated history, independently revokable\ncurl -X POST http://localhost:3000/emails \\\n  -H \"Authorization: Bearer <notifications-svc-key>\" \\\n  -F \"to=user@example.com\" \\\n  -F \"subject=Your order shipped\" \\\n  -F \"text=Tracking: #9876\"\n```\n\n---\n\n## Tech stack\n\n| Concern | Package |\n|---|---|\n| HTTP server | `express` 4 |\n| SMTP | `nodemailer` 6 |\n| Database | `node:sqlite` (built-in) |\n| File uploads | `multer` 1 |\n| Scheduler | `node-cron` 3 |\n| TUI rendering | `blessed` |\n| ID generation | `nanoid` 5 |\n| Runtime | Node.js ≥ 22.5 ESM |\n| Test runner | `node:test` (built-in) |\n\n---\n\n## Development\n\n```bash\ngit clone https://github.com/aks-builds/email-api\ncd email-api\nnpm install\nnpm test        # 37 tests, node:test built-in runner\n\n# Or install globally\nnpm install -g @aks-builds/email-api\n```\n\n---\n\n## License\n\nMIT © [aks-builds](https://github.com/aks-builds)\n","readmeFilename":"README.md"}