@adityanair98/api-oracle 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +216 -0
  3. package/dist/cli.d.ts +11 -0
  4. package/dist/cli.js +74 -0
  5. package/dist/dashboard/public/app.js +1004 -0
  6. package/dist/dashboard/public/index.html +142 -0
  7. package/dist/dashboard/public/public/app.js +1004 -0
  8. package/dist/dashboard/public/public/index.html +142 -0
  9. package/dist/dashboard/public/public/styles.css +1464 -0
  10. package/dist/dashboard/public/styles.css +1464 -0
  11. package/dist/dashboard/routes/api.d.ts +7 -0
  12. package/dist/dashboard/routes/api.js +245 -0
  13. package/dist/dashboard/server.d.ts +9 -0
  14. package/dist/dashboard/server.js +45 -0
  15. package/dist/index.d.ts +5 -0
  16. package/dist/index.js +23 -0
  17. package/dist/knowledge/db.d.ts +22 -0
  18. package/dist/knowledge/db.js +182 -0
  19. package/dist/knowledge/schema.d.ts +275 -0
  20. package/dist/knowledge/schema.js +135 -0
  21. package/dist/knowledge/scorer.d.ts +63 -0
  22. package/dist/knowledge/scorer.js +314 -0
  23. package/dist/knowledge/search.d.ts +37 -0
  24. package/dist/knowledge/search.js +111 -0
  25. package/dist/knowledge/synonyms.d.ts +36 -0
  26. package/dist/knowledge/synonyms.js +523 -0
  27. package/dist/knowledge/tfidf.d.ts +42 -0
  28. package/dist/knowledge/tfidf.js +138 -0
  29. package/dist/server.d.ts +9 -0
  30. package/dist/server.js +40 -0
  31. package/dist/tools/check-freshness.d.ts +9 -0
  32. package/dist/tools/check-freshness.js +95 -0
  33. package/dist/tools/compare-apis.d.ts +8 -0
  34. package/dist/tools/compare-apis.js +149 -0
  35. package/dist/tools/find-api.d.ts +9 -0
  36. package/dist/tools/find-api.js +120 -0
  37. package/dist/tools/get-setup-guide.d.ts +8 -0
  38. package/dist/tools/get-setup-guide.js +127 -0
  39. package/dist/updater/linter.d.ts +31 -0
  40. package/dist/updater/linter.js +219 -0
  41. package/dist/updater/report.d.ts +29 -0
  42. package/dist/updater/report.js +96 -0
  43. package/dist/updater/staleness.d.ts +39 -0
  44. package/dist/updater/staleness.js +66 -0
  45. package/dist/updater/version-tracker.d.ts +28 -0
  46. package/dist/updater/version-tracker.js +50 -0
  47. package/dist/utils/config.d.ts +11 -0
  48. package/dist/utils/config.js +13 -0
  49. package/dist/utils/logger.d.ts +20 -0
  50. package/dist/utils/logger.js +32 -0
  51. package/package.json +56 -0
  52. package/src/entries/ai/anthropic.json +95 -0
  53. package/src/entries/ai/eleven-labs.json +90 -0
  54. package/src/entries/ai/openai.json +95 -0
  55. package/src/entries/ai/replicate.json +87 -0
  56. package/src/entries/ai/resemble-ai.json +88 -0
  57. package/src/entries/ai/stability-ai.json +89 -0
  58. package/src/entries/analytics/posthog.json +88 -0
  59. package/src/entries/analytics/sentry.json +84 -0
  60. package/src/entries/auth/auth0.json +90 -0
  61. package/src/entries/auth/clerk.json +95 -0
  62. package/src/entries/cms/contentful.json +92 -0
  63. package/src/entries/cms/sanity.json +92 -0
  64. package/src/entries/cms/strapi.json +93 -0
  65. package/src/entries/commerce/medusa.json +91 -0
  66. package/src/entries/commerce/shopify-api.json +91 -0
  67. package/src/entries/communication/sendbird.json +85 -0
  68. package/src/entries/communication/stream-chat.json +94 -0
  69. package/src/entries/database/firebase.json +88 -0
  70. package/src/entries/database/neon.json +94 -0
  71. package/src/entries/database/planetscale.json +95 -0
  72. package/src/entries/database/supabase.json +94 -0
  73. package/src/entries/database/upstash.json +94 -0
  74. package/src/entries/devops/fly-io.json +90 -0
  75. package/src/entries/devops/netlify.json +90 -0
  76. package/src/entries/devops/railway.json +90 -0
  77. package/src/entries/devops/vercel.json +90 -0
  78. package/src/entries/email/mailgun.json +91 -0
  79. package/src/entries/email/postmark.json +91 -0
  80. package/src/entries/email/resend.json +89 -0
  81. package/src/entries/email/sendgrid.json +90 -0
  82. package/src/entries/forms/formspark.json +85 -0
  83. package/src/entries/forms/typeform.json +98 -0
  84. package/src/entries/infrastructure/aws-s3.json +104 -0
  85. package/src/entries/infrastructure/cloudflare-r2.json +92 -0
  86. package/src/entries/infrastructure/cloudflare-workers.json +92 -0
  87. package/src/entries/infrastructure/digital-ocean-spaces.json +87 -0
  88. package/src/entries/integration/nango.json +90 -0
  89. package/src/entries/integration/zapier.json +92 -0
  90. package/src/entries/maps/google-maps.json +89 -0
  91. package/src/entries/maps/mapbox.json +87 -0
  92. package/src/entries/media/deepgram.json +84 -0
  93. package/src/entries/media/imgix.json +84 -0
  94. package/src/entries/media/mux.json +94 -0
  95. package/src/entries/messaging/ably.json +94 -0
  96. package/src/entries/messaging/pusher.json +94 -0
  97. package/src/entries/messaging/twilio.json +94 -0
  98. package/src/entries/messaging/vonage.json +89 -0
  99. package/src/entries/notifications/knock.json +84 -0
  100. package/src/entries/notifications/novu.json +84 -0
  101. package/src/entries/notifications/onesignal.json +84 -0
  102. package/src/entries/payments/lemonsqueezy.json +91 -0
  103. package/src/entries/payments/paddle.json +90 -0
  104. package/src/entries/payments/paypal.json +91 -0
  105. package/src/entries/payments/razorpay.json +85 -0
  106. package/src/entries/payments/square.json +91 -0
  107. package/src/entries/payments/stripe.json +96 -0
  108. package/src/entries/scheduling/cal-com.json +90 -0
  109. package/src/entries/scheduling/calendly.json +90 -0
  110. package/src/entries/search/algolia.json +96 -0
  111. package/src/entries/security/arcjet.json +89 -0
  112. package/src/entries/security/snyk.json +90 -0
  113. package/src/entries/storage/cloudinary.json +93 -0
  114. package/src/entries/storage/uploadthing.json +90 -0
  115. package/src/entries/testing/browserstack.json +86 -0
  116. package/src/entries/testing/checkly.json +89 -0
  117. package/src/entries/workflow/inngest.json +88 -0
  118. package/src/entries/workflow/temporal.json +90 -0
  119. package/src/entries/workflow/trigger-dev.json +89 -0
@@ -0,0 +1,90 @@
1
+ {
2
+ "name": "Fly.io",
3
+ "slug": "fly-io",
4
+ "category": "devops",
5
+ "subcategory": "global-app-deployment",
6
+ "website": "https://fly.io",
7
+ "description": "Fly.io runs Docker containers on bare-metal hardware physically close to your users across 35+ global regions. Apps automatically deploy to multiple regions, reducing latency for international users without complex infrastructure configuration.",
8
+ "useCases": [
9
+ {
10
+ "task": "Deploy a containerized backend API close to users globally",
11
+ "fit": "perfect"
12
+ },
13
+ {
14
+ "task": "Run a persistent stateful application (not serverless)",
15
+ "fit": "perfect"
16
+ },
17
+ {
18
+ "task": "Host a database replica near users to reduce latency",
19
+ "fit": "perfect"
20
+ },
21
+ {
22
+ "task": "Deploy a long-running WebSocket server",
23
+ "fit": "good"
24
+ }
25
+ ],
26
+ "auth": {
27
+ "method": "api_key",
28
+ "setupSteps": [
29
+ "Install flyctl: curl -L https://fly.io/install.sh | sh",
30
+ "Authenticate: fly auth login (opens browser)",
31
+ "In your project directory: fly launch (auto-detects stack, creates fly.toml and Dockerfile if absent)",
32
+ "Set secrets: fly secrets set KEY=value",
33
+ "Deploy: fly deploy"
34
+ ],
35
+ "envVarName": "FLY_API_TOKEN",
36
+ "codeSnippet": "# fly.toml — primary app configuration (not a code snippet but the auth/config entry point)\n# Generate a deploy token (scoped to one app) with:\n# fly tokens create deploy -a your-app-name\n# Then set FLY_API_TOKEN in your CI environment and run:\n# fly deploy --remote-only\n\n# Dockerfile (multi-stage build for a Node.js app):\n# FROM node:20-alpine AS builder\n# WORKDIR /app\n# COPY package*.json ./\n# RUN npm ci\n# COPY . .\n# RUN npm run build\n#\n# FROM node:20-alpine\n# WORKDIR /app\n# COPY --from=builder /app/dist ./dist\n# COPY --from=builder /app/node_modules ./node_modules\n# EXPOSE 3000\n# CMD [\"node\", \"dist/index.js\"]"
37
+ },
38
+ "pricing": {
39
+ "model": "freemium",
40
+ "freeTier": "3 shared-cpu-1x 256MB VMs, 3GB persistent volumes, 160GB outbound bandwidth/month",
41
+ "startingPrice": "Usage-based: ~$1.94/month for shared-cpu-1x 256MB VM running 24/7",
42
+ "costPer": "$0.0000008/MB-second RAM, $0.00000012/vCPU-second, $0.15/GB outbound transfer after 160GB",
43
+ "pricingUrl": "https://fly.io/docs/about/pricing/"
44
+ },
45
+ "rateLimits": {
46
+ "tier": "free tier",
47
+ "limit": "3 VMs on free tier, each 256MB RAM, shared CPU. No request rate limits — bounded by VM resources.",
48
+ "notes": "Free tier VMs use shared CPUs that are throttled under high load. There are no API rate limits — throughput is constrained by VM RAM and CPU. Adding more regions costs additional per-VM fees. Free tier VMs do NOT auto-scale to zero.",
49
+ "retryStrategy": "Fly.io auto-restarts crashed VMs. Use Fly's health checks and graceful shutdown handling for zero-downtime deploys."
50
+ },
51
+ "sdk": {
52
+ "primaryLanguage": "typescript",
53
+ "installCommand": "npm install --save-exact @fly-apps/fly-admin",
54
+ "importStatement": "// Primarily CLI-driven: flyctl. REST API available for automation.",
55
+ "otherLanguages": ["python", "go", "ruby", "elixir"]
56
+ },
57
+ "codeExamples": [
58
+ {
59
+ "title": "fly.toml — app configuration",
60
+ "language": "typescript",
61
+ "code": "// fly.toml is TOML, not TypeScript — shown here for reference alongside the Node.js app it configures\n//\n// app = 'my-typescript-api'\n// primary_region = 'iad' # US East (IAD) as primary region\n//\n// [build]\n// dockerfile = 'Dockerfile'\n//\n// [env]\n// PORT = '3000'\n// NODE_ENV = 'production'\n//\n// [http_service]\n// internal_port = 3000\n// force_https = true\n// auto_stop_machines = false # keep alive; set true to stop on idle\n// auto_start_machines = true\n// min_machines_running = 1\n//\n// [[http_service.checks]]\n// grace_period = '10s'\n// interval = '30s'\n// method = 'GET'\n// path = '/health'\n// timeout = '5s'\n//\n// [[vm]]\n// memory = '512mb'\n// cpu_kind = 'shared'\n// cpus = 1\n\n// Corresponding Express app (src/index.ts)\nimport express from 'express';\n\nconst app = express();\nconst PORT = Number(process.env.PORT ?? 3000);\n\napp.get('/health', (_req, res) => {\n res.json({ status: 'ok', region: process.env.FLY_REGION ?? 'local' });\n});\n\napp.get('/api/hello', (_req, res) => {\n res.json({\n message: 'Hello from Fly.io!',\n region: process.env.FLY_REGION,\n machineId: process.env.FLY_MACHINE_ID,\n });\n});\n\napp.listen(PORT, '0.0.0.0', () => {\n console.log(`Listening on 0.0.0.0:${PORT}`);\n});",
62
+ "notes": "Always bind to 0.0.0.0 (not 127.0.0.1) inside Fly VMs or your server won't be reachable from outside the container. Fly injects FLY_REGION, FLY_APP_NAME, and FLY_MACHINE_ID as environment variables — useful for debugging and routing logic."
63
+ },
64
+ {
65
+ "title": "Dockerfile for Node.js app on Fly.io",
66
+ "language": "typescript",
67
+ "code": "// Dockerfile — multi-stage build to minimize final image size\n// Place this in your project root alongside fly.toml\n//\n// ---- Stage 1: Build ----\n// FROM node:20-alpine AS builder\n// WORKDIR /app\n//\n// # Install dependencies first (layer cache optimization)\n// COPY package.json package-lock.json ./\n// RUN npm ci --frozen-lockfile\n//\n// # Copy source and compile TypeScript\n// COPY tsconfig.json ./\n// COPY src ./src\n// RUN npx tsc --project tsconfig.json\n//\n// ---- Stage 2: Production image ----\n// FROM node:20-alpine AS runner\n// WORKDIR /app\n// ENV NODE_ENV=production\n//\n// # Only copy production dependencies\n// COPY package.json package-lock.json ./\n// RUN npm ci --frozen-lockfile --omit=dev\n//\n// # Copy compiled output from build stage\n// COPY --from=builder /app/dist ./dist\n//\n// # Run as non-root user\n// RUN addgroup -S appgroup && adduser -S appuser -G appgroup\n// USER appuser\n//\n// EXPOSE 3000\n// CMD [\"node\", \"dist/index.js\"]\n\n// Verify your image locally before deploying:\n// docker build -t my-app . && docker run -p 3000:3000 my-app\n\n// Deploy to Fly.io:\n// fly deploy --remote-only\n\nexport {}; // make this a valid TypeScript module",
68
+ "notes": "The --remote-only flag builds the Docker image on Fly's remote builder instead of locally — useful in CI pipelines where Docker is unavailable. Use `fly logs` to tail application logs in real time after deployment. The multi-stage build keeps the final image under 200MB for most Node.js apps."
69
+ }
70
+ ],
71
+ "gotchas": [
72
+ "Fly.io is NOT serverless — VMs run continuously and you are billed for uptime regardless of request volume. A 256MB shared-cpu VM running 24/7 costs approximately $1.94/month. If you need true scale-to-zero to eliminate idle costs, set `auto_stop_machines = true` in fly.toml, but be aware this introduces cold-start latency on the first request after a stop.",
73
+ "The free tier has no published SLA and no guaranteed CPU performance. Shared CPUs are burst-limited and can be throttled under high load across the host machine. For latency-sensitive production workloads use performance-1x or higher machine types, which provide dedicated vCPU time.",
74
+ "Secrets (environment variables containing sensitive values) must be set via the flyctl CLI using `fly secrets set KEY=value` — they cannot be placed in fly.toml (which is committed to git) and are NOT automatically synced on `fly deploy`. Forgetting to set secrets in a new region or after a team member runs `fly deploy` from a fresh machine is a common source of missing-credentials runtime errors.",
75
+ "Persistent volumes in Fly.io are single-availability-zone and are not replicated. If the physical host or AZ hosting your volume has an outage, your data is inaccessible or at risk of loss. For any data you cannot afford to lose, use a managed database service (Neon, Supabase, PlanetScale) rather than a Fly volume."
76
+ ],
77
+ "reliability": {
78
+ "uptimeGuarantee": "99.9% uptime target (no published SLA on free tier)",
79
+ "statusPageUrl": "https://status.flyio.net",
80
+ "notes": "Fly.io uses a globally distributed Anycast network with 35+ regions. VMs are automatically restarted on failure. No formal SLA on free or Hobby tiers; enterprise contracts available."
81
+ },
82
+ "qualityScore": 8,
83
+ "qualityJustification": "Best option for globally distributed apps that need persistent state, WebSockets, or long-running processes. Docker-native deployment model gives maximum flexibility. The global Anycast network genuinely reduces latency for international users. Main friction: CLI-heavy workflow and no managed HTTPS cert automation as polished as Vercel.",
84
+ "alternatives": ["railway", "vercel", "netlify", "cloudflare-workers"],
85
+ "complementary": ["neon", "upstash", "supabase", "cloudflare-workers"],
86
+ "bestFor": "Running containerized apps globally close to users, with persistent volumes and full control over the runtime environment",
87
+ "lastVerified": "2026-02-25",
88
+ "entryVersion": 1,
89
+ "addedBy": "claude-code-session-4"
90
+ }
@@ -0,0 +1,90 @@
1
+ {
2
+ "name": "Netlify",
3
+ "slug": "netlify",
4
+ "category": "devops",
5
+ "subcategory": "frontend-deployment",
6
+ "website": "https://netlify.com",
7
+ "description": "Netlify is a git-based platform for web deployment with continuous deployment, serverless functions, edge functions, split testing, and built-in form handling — making it a full-featured hosting solution for JAMstack and static sites.",
8
+ "useCases": [
9
+ {
10
+ "task": "Deploy a static site or JAMstack application",
11
+ "fit": "perfect"
12
+ },
13
+ {
14
+ "task": "Add serverless functions to a frontend app",
15
+ "fit": "perfect"
16
+ },
17
+ {
18
+ "task": "Set up continuous deployment from GitHub",
19
+ "fit": "perfect"
20
+ },
21
+ {
22
+ "task": "A/B testing with split traffic between branches",
23
+ "fit": "good"
24
+ }
25
+ ],
26
+ "auth": {
27
+ "method": "api_key",
28
+ "setupSteps": [
29
+ "Sign up at netlify.com",
30
+ "Create a new site from the dashboard",
31
+ "Connect your GitHub, GitLab, or Bitbucket repository",
32
+ "Netlify auto-deploys on every push to your configured production branch",
33
+ "Generate a personal access token at app.netlify.com/user/applications and set NETLIFY_AUTH_TOKEN"
34
+ ],
35
+ "envVarName": "NETLIFY_AUTH_TOKEN",
36
+ "codeSnippet": "// Trigger a deploy via the Netlify REST API\nconst response = await fetch(\n `https://api.netlify.com/api/v1/sites/${process.env.NETLIFY_SITE_ID}/builds`,\n {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${process.env.NETLIFY_AUTH_TOKEN}`,\n 'Content-Type': 'application/json',\n },\n }\n);\nconst build = await response.json();\nconsole.log('Build triggered:', build.id);"
37
+ },
38
+ "pricing": {
39
+ "model": "freemium",
40
+ "freeTier": "Starter: 100GB bandwidth/month, 300 build minutes/month, 125K serverless invocations/month",
41
+ "startingPrice": "$19/month (Pro) for 400GB bandwidth, 25K build minutes",
42
+ "costPer": "Additional bandwidth at $0.55/GB, additional build minutes at $0.025/minute above included.",
43
+ "pricingUrl": "https://netlify.com/pricing"
44
+ },
45
+ "rateLimits": {
46
+ "tier": "free tier",
47
+ "limit": "125,000 serverless function invocations/month, 10s function timeout (free), 300 build minutes/month",
48
+ "notes": "Netlify Functions time out at 10 seconds on the free Starter plan and 26 seconds on paid plans. Invocation count resets monthly. Background functions (async, no response required) are available on paid plans only.",
49
+ "retryStrategy": "Functions timeout at 10s on free tier (26s on paid). Implement timeouts and fallbacks in client code."
50
+ },
51
+ "sdk": {
52
+ "primaryLanguage": "typescript",
53
+ "installCommand": "npm install --save-exact netlify-cli --save-dev",
54
+ "importStatement": "// No runtime SDK — use Netlify Functions or the REST API",
55
+ "otherLanguages": ["javascript", "python", "go"]
56
+ },
57
+ "codeExamples": [
58
+ {
59
+ "title": "Netlify Function (serverless)",
60
+ "language": "typescript",
61
+ "code": "// netlify/functions/hello.ts\nimport type { Handler, HandlerEvent, HandlerContext } from '@netlify/functions';\n\ninterface RequestBody {\n name?: string;\n}\n\nexport const handler: Handler = async (\n event: HandlerEvent,\n _context: HandlerContext\n) => {\n if (event.httpMethod !== 'POST') {\n return {\n statusCode: 405,\n body: JSON.stringify({ error: 'Method Not Allowed' }),\n };\n }\n\n const body: RequestBody = event.body ? JSON.parse(event.body) : {};\n const name = body.name ?? 'World';\n\n return {\n statusCode: 200,\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ message: `Hello, ${name}!`, timestamp: Date.now() }),\n };\n};",
62
+ "notes": "Place functions in netlify/functions/*.ts and they are automatically deployed. Install types with: npm install --save-exact @netlify/functions. The function is available at /.netlify/functions/hello. Use netlify dev locally to test functions before deploying."
63
+ },
64
+ {
65
+ "title": "Trigger deploy via REST API",
66
+ "language": "typescript",
67
+ "code": "interface NetlifyBuild {\n id: string;\n deploy_id: string;\n done: boolean;\n error: string | null;\n created_at: string;\n}\n\nasync function triggerNetlifyDeploy(\n siteId: string,\n authToken: string\n): Promise<NetlifyBuild> {\n const response = await fetch(\n `https://api.netlify.com/api/v1/sites/${siteId}/builds`,\n {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${authToken}`,\n 'Content-Type': 'application/json',\n },\n }\n );\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Netlify deploy failed: ${response.status} ${errorText}`);\n }\n\n const build = (await response.json()) as NetlifyBuild;\n console.log(`Deploy triggered. Build ID: ${build.id}`);\n return build;\n}\n\n// Usage\nawait triggerNetlifyDeploy(\n process.env.NETLIFY_SITE_ID!,\n process.env.NETLIFY_AUTH_TOKEN!\n);",
68
+ "notes": "Use the Netlify REST API to trigger deploys from CI pipelines or external webhooks. You can also create a deploy hook URL in the Netlify UI (Site Settings > Build & Deploy > Build hooks) and POST to it without authentication."
69
+ }
70
+ ],
71
+ "gotchas": [
72
+ "Netlify Functions have a 10MB unzipped bundle size limit and a 50MB zipped limit — dependencies like puppeteer, sharp, or large ML models will exceed this and cause deploy failures. Use Netlify's Large Media or an external runner (AWS Lambda, Fly.io) for size-intensive functions.",
73
+ "Build minutes are shared across ALL sites in an account, not per site. A large monorepo or a site with frequent commits can exhaust the free tier's 300 monthly minutes in a few days, blocking all other sites in the account from deploying until the next billing cycle.",
74
+ "Netlify Forms only intercepts HTML form submissions that Netlify's build bot detects at build time — forms dynamically rendered by JavaScript or submitted via fetch/XHR are invisible to Netlify. You must include a hidden input (`<input type='hidden' name='form-name' value='your-form-name'>`) for JavaScript-submitted forms to be captured.",
75
+ "Environment variables are NOT exposed to client-side JavaScript by default regardless of framework. Only variables prefixed according to your framework's convention (e.g., NEXT_PUBLIC_ for Next.js, GATSBY_ for Gatsby, VITE_ for Vite) are injected into the browser bundle — all others are server-only."
76
+ ],
77
+ "reliability": {
78
+ "uptimeGuarantee": "99.99% uptime SLA on paid plans",
79
+ "statusPageUrl": "https://netlifystatus.com",
80
+ "notes": "Netlify serves static assets from a global CDN backed by multiple cloud providers. Serverless functions run in AWS Lambda under the hood. Automatic failover for CDN nodes."
81
+ },
82
+ "qualityScore": 8,
83
+ "qualityJustification": "Strong alternative to Vercel with a more generous free tier (125K function invocations vs Vercel's 100GB-hours). Better built-in features for forms and identity. Slightly less polished DX for Next.js but excellent for Gatsby, Hugo, and static sites.",
84
+ "alternatives": ["vercel", "railway", "fly-io", "cloudflare-workers"],
85
+ "complementary": ["supabase", "neon", "cloudflare-workers", "resend", "clerk"],
86
+ "bestFor": "JAMstack and static site deployments with built-in form handling, identity, and continuous deployment from git",
87
+ "lastVerified": "2026-02-25",
88
+ "entryVersion": 1,
89
+ "addedBy": "claude-code-session-4"
90
+ }
@@ -0,0 +1,90 @@
1
+ {
2
+ "name": "Railway",
3
+ "slug": "railway",
4
+ "category": "devops",
5
+ "subcategory": "app-deployment",
6
+ "website": "https://railway.app",
7
+ "description": "Railway is an infrastructure platform that deploys any language or framework — Node.js, Python, Go, Ruby — along with databases like PostgreSQL and Redis, with zero Dockerfile configuration required. Nixpacks auto-detects your stack and handles the rest.",
8
+ "useCases": [
9
+ {
10
+ "task": "Deploy a Node.js, Python, or Go backend server",
11
+ "fit": "perfect"
12
+ },
13
+ {
14
+ "task": "Host a PostgreSQL or Redis database with automatic backups",
15
+ "fit": "perfect"
16
+ },
17
+ {
18
+ "task": "Deploy a full-stack app with web server and database together",
19
+ "fit": "perfect"
20
+ },
21
+ {
22
+ "task": "Run scheduled cron jobs or background workers",
23
+ "fit": "good"
24
+ }
25
+ ],
26
+ "auth": {
27
+ "method": "api_key",
28
+ "setupSteps": [
29
+ "Sign up at railway.app (GitHub login recommended)",
30
+ "Create a new project from the dashboard",
31
+ "Connect your GitHub repository or use `railway init` from the CLI",
32
+ "Railway auto-detects your stack with Nixpacks and deploys on every push",
33
+ "Generate an API token at railway.app/account/tokens and set RAILWAY_TOKEN"
34
+ ],
35
+ "envVarName": "RAILWAY_TOKEN",
36
+ "codeSnippet": "import { RailwayClient } from '@railway/sdk';\n\nconst client = new RailwayClient({ token: process.env.RAILWAY_TOKEN! });\n\nconst services = await client.services.list({\n projectId: process.env.RAILWAY_PROJECT_ID!,\n});\nconsole.log('Services:', services);"
37
+ },
38
+ "pricing": {
39
+ "model": "usage_based",
40
+ "freeTier": null,
41
+ "startingPrice": "$5/month Hobby plan (includes $5 of usage credit)",
42
+ "costPer": "$0.000463/vCPU-minute, $0.0000016/MB RAM-minute, $0.20/GB storage",
43
+ "pricingUrl": "https://railway.app/pricing"
44
+ },
45
+ "rateLimits": {
46
+ "tier": "Hobby plan",
47
+ "limit": "No hard request rate limits — limits are on compute resources (vCPU, RAM). Deployments are limited to 512MB RAM and 2 vCPU on Hobby plan.",
48
+ "notes": "Railway bills purely on resource consumption (CPU + RAM per minute). There are no request-count limits. Hobby plan services sleep after inactivity by default, which reduces costs but introduces cold-start latency.",
49
+ "retryStrategy": "Handle application-level retries. Railway provides health checks and automatic restarts on crash."
50
+ },
51
+ "sdk": {
52
+ "primaryLanguage": "typescript",
53
+ "installCommand": "npm install --save-exact @railway/sdk",
54
+ "importStatement": "import { RailwayClient } from '@railway/sdk';",
55
+ "otherLanguages": ["python", "go", "ruby", "java"]
56
+ },
57
+ "codeExamples": [
58
+ {
59
+ "title": "Deploy via railway.json config",
60
+ "language": "typescript",
61
+ "code": "// railway.json — place in project root to configure Railway build and deploy\n// This is a JSON config file, not TypeScript, but shown here for reference\n//\n// {\n// \"$schema\": \"https://railway.app/railway.schema.json\",\n// \"build\": {\n// \"builder\": \"NIXPACKS\"\n// },\n// \"deploy\": {\n// \"startCommand\": \"node dist/index.js\",\n// \"healthcheckPath\": \"/health\",\n// \"healthcheckTimeout\": 100,\n// \"restartPolicyType\": \"ON_FAILURE\",\n// \"restartPolicyMaxRetries\": 10\n// }\n// }\n\n// Corresponding Express health check endpoint (src/index.ts):\nimport express from 'express';\n\nconst app = express();\nconst PORT = process.env.PORT ?? 3000;\n\napp.get('/health', (_req, res) => {\n res.json({ status: 'ok', uptime: process.uptime() });\n});\n\napp.listen(PORT, () => {\n console.log(`Server running on port ${PORT}`);\n});",
62
+ "notes": "Railway injects a PORT environment variable automatically — always use process.env.PORT rather than hardcoding a port. The railway.json schema supports custom build commands, health checks, and restart policies. Run `railway up` to deploy from your terminal without pushing to git."
63
+ },
64
+ {
65
+ "title": "Query Railway API with SDK",
66
+ "language": "typescript",
67
+ "code": "import { RailwayClient } from '@railway/sdk';\n\ninterface ServiceInfo {\n id: string;\n name: string;\n}\n\nasync function listProjectServices(\n projectId: string\n): Promise<ServiceInfo[]> {\n const client = new RailwayClient({\n token: process.env.RAILWAY_TOKEN!,\n });\n\n const services = await client.services.list({ projectId });\n\n return services.map((service) => ({\n id: service.id,\n name: service.name,\n }));\n}\n\nasync function triggerRedeployment(\n serviceId: string,\n environmentId: string\n): Promise<void> {\n const client = new RailwayClient({\n token: process.env.RAILWAY_TOKEN!,\n });\n\n await client.deployments.create({\n serviceId,\n environmentId,\n });\n\n console.log(`Redeployment triggered for service ${serviceId}`);\n}\n\n// List services and redeploy the first one\nconst services = await listProjectServices(process.env.RAILWAY_PROJECT_ID!);\nconsole.log('Services:', services);\n\nif (services.length > 0) {\n await triggerRedeployment(services[0].id, process.env.RAILWAY_ENVIRONMENT_ID!);\n}",
68
+ "notes": "The Railway SDK wraps the GraphQL API. Alternatively you can query the Railway GraphQL API directly at https://backboard.railway.app/graphql/v2 with a Bearer token. The SDK is in early development — the GraphQL API is more stable for production automation."
69
+ }
70
+ ],
71
+ "gotchas": [
72
+ "Railway removed its free tier in 2023. The Hobby plan has a $5/month minimum charge that applies even if your usage is zero — you will be billed $5 regardless of whether you deploy anything. There is no purely free option; plan accordingly before using Railway for side projects or experiments.",
73
+ "Hobby plan services sleep after a period of inactivity to reduce costs. The first HTTP request after a sleep period incurs a cold-start delay while the container restarts. For production services that require consistent low-latency responses, upgrade to the Pro plan or implement a keep-alive ping (e.g., an uptime monitor hitting /health every 5 minutes).",
74
+ "Railway does not provide a static outbound IP address on the Hobby plan. If any external service you call (a managed database, a payment provider, or a third-party API) requires IP allowlisting for security, you cannot use Railway's Hobby plan — you must upgrade to Pro to get a dedicated static IP.",
75
+ "Persistent volumes in Railway attach to a single service instance only. If you scale a service to multiple replicas, each replica gets its own isolated volume — there is no shared filesystem between replicas. Sharing state across replicas requires an external store (Redis, PostgreSQL, S3) rather than the local filesystem."
76
+ ],
77
+ "reliability": {
78
+ "uptimeGuarantee": "Uptime SLA not published; ~99.9% in practice",
79
+ "statusPageUrl": "https://status.railway.app",
80
+ "notes": "Railway runs on AWS infrastructure with automatic health checks and container restarts on failure. No published SLA for the Hobby plan. Pro plan customers have access to priority support."
81
+ },
82
+ "qualityScore": 7,
83
+ "qualityJustification": "Excellent developer experience for deploying any app without Dockerfile knowledge (uses Nixpacks for auto-detection). Best Heroku alternative with auto-provisioned databases. Loses points for removing free tier and limited documentation for advanced configurations.",
84
+ "alternatives": ["fly-io", "vercel", "netlify"],
85
+ "complementary": ["neon", "supabase", "stripe", "resend"],
86
+ "bestFor": "Deploying full-stack applications with databases, background workers, and cron jobs — the closest modern replacement for Heroku",
87
+ "lastVerified": "2026-02-25",
88
+ "entryVersion": 1,
89
+ "addedBy": "claude-code-session-4"
90
+ }
@@ -0,0 +1,90 @@
1
+ {
2
+ "name": "Vercel",
3
+ "slug": "vercel",
4
+ "category": "devops",
5
+ "subcategory": "frontend-deployment",
6
+ "website": "https://vercel.com",
7
+ "description": "Vercel is the premier deployment platform for Next.js, React, and frontend frameworks. It provides git-based deployments, instant preview URLs per pull request, a global edge network, and serverless functions — shipping from `git push` to production in seconds.",
8
+ "useCases": [
9
+ {
10
+ "task": "Deploy a Next.js application to production",
11
+ "fit": "perfect"
12
+ },
13
+ {
14
+ "task": "Add serverless API routes to a frontend app",
15
+ "fit": "perfect"
16
+ },
17
+ {
18
+ "task": "Set up preview deployments for every pull request",
19
+ "fit": "perfect"
20
+ },
21
+ {
22
+ "task": "Deploy a static site with global CDN",
23
+ "fit": "perfect"
24
+ }
25
+ ],
26
+ "auth": {
27
+ "method": "api_key",
28
+ "setupSteps": [
29
+ "Sign up at vercel.com",
30
+ "Create a new project from the dashboard",
31
+ "Connect your GitHub, GitLab, or Bitbucket repository",
32
+ "Vercel auto-deploys on every push to your default branch",
33
+ "Generate an API token at vercel.com/account/tokens and set VERCEL_TOKEN"
34
+ ],
35
+ "envVarName": "VERCEL_TOKEN",
36
+ "codeSnippet": "import { Vercel } from '@vercel/sdk';\n\nconst vercel = new Vercel({ bearerToken: process.env.VERCEL_TOKEN });\n\nconst deployments = await vercel.deployments.getDeployments({});\nconsole.log(deployments);"
37
+ },
38
+ "pricing": {
39
+ "model": "freemium",
40
+ "freeTier": "Hobby plan: unlimited personal projects, 100GB bandwidth/month, 100GB-hours serverless function execution",
41
+ "startingPrice": "$20/user/month (Pro)",
42
+ "costPer": "Pro: $40/month for 2 seats, $20/seat thereafter. Additional bandwidth at $0.15/GB above included.",
43
+ "pricingUrl": "https://vercel.com/pricing"
44
+ },
45
+ "rateLimits": {
46
+ "tier": "free tier",
47
+ "limit": "100GB bandwidth/month, 100GB-hours serverless execution, 6000 build minutes/month, 12 serverless function regions",
48
+ "notes": "Serverless functions time out at 10 seconds on the Hobby plan and up to 300 seconds on Pro/Enterprise. Build concurrency is limited to 1 concurrent build on Hobby.",
49
+ "retryStrategy": "Functions have 10s (Hobby) or 60s (Pro) timeout. Handle timeout errors with retry logic in client."
50
+ },
51
+ "sdk": {
52
+ "primaryLanguage": "typescript",
53
+ "installCommand": "npm install --save-exact @vercel/sdk",
54
+ "importStatement": "import { Vercel } from '@vercel/sdk';",
55
+ "otherLanguages": ["python", "go"]
56
+ },
57
+ "codeExamples": [
58
+ {
59
+ "title": "Deploy via CLI (most common)",
60
+ "language": "typescript",
61
+ "code": "import { Vercel } from '@vercel/sdk';\n\nconst vercel = new Vercel({\n bearerToken: process.env.VERCEL_TOKEN!,\n});\n\n// List the 5 most recent deployments for a project\nasync function listDeployments(projectId: string): Promise<void> {\n const result = await vercel.deployments.getDeployments({\n projectId,\n limit: 5,\n });\n\n for (const deployment of result.deployments) {\n console.log(\n `[${deployment.state}] ${deployment.url} — ${new Date(\n deployment.createdAt\n ).toISOString()}`\n );\n }\n}\n\nlistDeployments('prj_your_project_id').catch(console.error);",
62
+ "notes": "Install the Vercel CLI globally with `npm i -g vercel` for one-off deploys. Use `vercel --prod` to deploy to production. The @vercel/sdk is best for programmatic automation — CI pipelines, deployment dashboards, or listing/cancelling deployments."
63
+ },
64
+ {
65
+ "title": "Create a serverless API route (Next.js)",
66
+ "language": "typescript",
67
+ "code": "// app/api/hello/route.ts (Next.js App Router)\nimport { NextRequest, NextResponse } from 'next/server';\n\nexport const runtime = 'edge'; // optional: run on Vercel Edge Network\n\nexport async function GET(req: NextRequest): Promise<NextResponse> {\n const { searchParams } = new URL(req.url);\n const name = searchParams.get('name') ?? 'World';\n\n return NextResponse.json(\n { message: `Hello, ${name}!`, timestamp: Date.now() },\n { status: 200 }\n );\n}\n\nexport async function POST(req: NextRequest): Promise<NextResponse> {\n const body = await req.json() as { name?: string };\n\n if (!body.name) {\n return NextResponse.json({ error: 'name is required' }, { status: 400 });\n }\n\n return NextResponse.json({ message: `Hello, ${body.name}!` }, { status: 201 });\n}",
68
+ "notes": "Placing a file at app/api/*/route.ts automatically becomes a serverless function on Vercel. Set `export const runtime = 'edge'` to run on the global edge network instead of a single region. Edge functions have a 25MB memory limit vs 1GB for standard serverless functions."
69
+ }
70
+ ],
71
+ "gotchas": [
72
+ "Hobby plan users cannot attach custom domains to production deployments on personal projects — all personal deployments are served from *.vercel.app subdomains only. A Vercel Pro or Teams plan is required to use a custom domain on a team project.",
73
+ "Serverless functions on the Hobby plan have a hard 10-second execution timeout that cannot be configured. Functions that call slow third-party APIs, run LLM inference, or process large files will be killed at 10 seconds. Upgrading to Pro unlocks up to 300 seconds.",
74
+ "Each git push to any branch triggers a new deployment — there is no staging environment by default. Use Vercel's built-in Environment targeting (Preview vs Production) and configure branch-to-environment mappings explicitly to avoid accidentally shipping preview code to production.",
75
+ "Environment variables are scoped per environment (Development, Preview, Production) and must be configured separately for each. A variable added to the Preview environment does NOT automatically appear in Production — forgetting this is a common source of 'undefined env var' bugs after promotion to production."
76
+ ],
77
+ "reliability": {
78
+ "uptimeGuarantee": "99.99% uptime SLA on Pro and Enterprise plans",
79
+ "statusPageUrl": "https://www.vercel-status.com",
80
+ "notes": "Vercel runs on a multi-region edge network with automatic failover. Static assets and edge functions are distributed globally via Anycast. Serverless function regions are user-selectable on Pro."
81
+ },
82
+ "qualityScore": 9,
83
+ "qualityJustification": "Industry standard for Next.js and React deployments. Git push to deploy, instant previews per PR, and a global edge network make it the fastest path from code to production. Serverless functions are first-class citizens.",
84
+ "alternatives": ["netlify", "railway", "fly-io", "cloudflare-workers"],
85
+ "complementary": ["neon", "supabase", "planetscale", "upstash", "cloudflare-workers", "resend", "clerk"],
86
+ "bestFor": "Deploying Next.js, React, and other frontend frameworks with zero-config git deployments, preview environments, and serverless functions",
87
+ "lastVerified": "2026-02-25",
88
+ "entryVersion": 1,
89
+ "addedBy": "claude-code-session-4"
90
+ }
@@ -0,0 +1,91 @@
1
+ {
2
+ "name": "Mailgun",
3
+ "slug": "mailgun",
4
+ "category": "email",
5
+ "subcategory": "transactional-email",
6
+ "website": "https://www.mailgun.com",
7
+ "description": "Mailgun (by Sinch) is a transactional email API with advanced deliverability features, email validation, and parsing capabilities. Used extensively by SaaS companies for transactional and notification emails. Provides detailed delivery analytics, A/B testing for email, email routing, and inbound email parsing — receive and process incoming emails via webhook.",
8
+ "useCases": [
9
+ {
10
+ "task": "Send transactional emails with high deliverability",
11
+ "fit": "perfect"
12
+ },
13
+ {
14
+ "task": "Parse and process incoming emails via webhook",
15
+ "fit": "perfect"
16
+ },
17
+ {
18
+ "task": "Validate email addresses before adding to a list",
19
+ "fit": "good"
20
+ },
21
+ {
22
+ "task": "Send bulk notification emails with delivery tracking",
23
+ "fit": "good"
24
+ }
25
+ ],
26
+ "auth": {
27
+ "method": "api_key",
28
+ "setupSteps": [
29
+ "Create a Mailgun account at mailgun.com",
30
+ "Go to Sending > Domains and add your sending domain",
31
+ "Complete DNS verification by adding the provided MX, TXT, and CNAME records",
32
+ "Go to Settings > API Keys",
33
+ "Click 'Add new key' to create a Private API key",
34
+ "Set MAILGUN_API_KEY and MAILGUN_DOMAIN environment variables"
35
+ ],
36
+ "envVarName": "MAILGUN_API_KEY",
37
+ "codeSnippet": "import Mailgun from 'mailgun.js';\nimport FormData from 'form-data';\n\nconst mailgun = new Mailgun(FormData);\nconst client = mailgun.client({\n username: 'api',\n key: process.env.MAILGUN_API_KEY ?? '',\n // EU accounts: url: 'https://api.eu.mailgun.net'\n});"
38
+ },
39
+ "pricing": {
40
+ "model": "freemium",
41
+ "freeTier": "Free trial: 100 emails/day for 3 months; then Flex plan with 1,000 free emails/month ongoing",
42
+ "startingPrice": "$15/month (Foundation) for 50,000 emails/month with email validation included",
43
+ "costPer": "Flex plan: first 1,000 emails/month free, then $0.80/1,000 emails. Foundation: $15/month flat for 50K emails.",
44
+ "pricingUrl": "https://www.mailgun.com/pricing/"
45
+ },
46
+ "rateLimits": {
47
+ "tier": "Flex plan",
48
+ "limit": "100 emails/hour on Flex plan (free). No hourly rate limit on paid Foundation and Scale plans. API request rate limit: up to 5,000 requests/second on Enterprise.",
49
+ "notes": "The 100 emails/hour limit on the Flex plan affects burst sending — drip campaigns or automated sequences can hit this limit. Batch email sends are queued and processed at the allowed rate. Paid plans remove the hourly cap.",
50
+ "retryStrategy": "Implement retry on 5xx errors with exponential backoff. Use Mailgun webhooks for delivery failure events rather than polling the API for send status."
51
+ },
52
+ "sdk": {
53
+ "primaryLanguage": "typescript",
54
+ "installCommand": "npm install --save-exact mailgun.js form-data",
55
+ "importStatement": "import Mailgun from 'mailgun.js';\nimport FormData from 'form-data';",
56
+ "otherLanguages": ["python", "ruby", "java", "php"]
57
+ },
58
+ "codeExamples": [
59
+ {
60
+ "title": "Send a transactional email with template variables",
61
+ "language": "typescript",
62
+ "code": "import Mailgun from 'mailgun.js';\nimport FormData from 'form-data';\n\nconst mailgun = new Mailgun(FormData);\nconst client = mailgun.client({\n username: 'api',\n key: process.env.MAILGUN_API_KEY ?? '',\n});\n\nconst DOMAIN = process.env.MAILGUN_DOMAIN ?? '';\n\ninterface SendEmailOptions {\n to: string;\n subject: string;\n templateName: string;\n variables: Record<string, string>;\n}\n\nasync function sendTransactionalEmail(options: SendEmailOptions): Promise<string> {\n const result = await client.messages.create(DOMAIN, {\n from: `My App <noreply@${DOMAIN}>`,\n to: [options.to],\n subject: options.subject,\n template: options.templateName,\n 'h:X-Mailgun-Variables': JSON.stringify(options.variables),\n });\n\n console.log('Message queued:', result.id);\n return result.id;\n}\n\n// Send a password reset email using a Mailgun template\nconst messageId = await sendTransactionalEmail({\n to: 'user@example.com',\n subject: 'Reset your password',\n templateName: 'password-reset',\n variables: {\n name: 'Alice',\n reset_link: 'https://myapp.com/reset?token=abc123',\n expiry_hours: '24',\n },\n});",
63
+ "notes": "Templates must be created in the Mailgun dashboard before use. Pass template variables as a JSON string in the 'h:X-Mailgun-Variables' header. Mailgun template syntax uses Handlebars ({{variable_name}})."
64
+ },
65
+ {
66
+ "title": "Parse an inbound email via Mailgun webhook",
67
+ "language": "typescript",
68
+ "code": "import express, { Request, Response } from 'express';\nimport crypto from 'crypto';\n\nconst app = express();\n\n// Mailgun sends inbound emails as multipart/form-data\napp.use(express.urlencoded({ extended: true }));\n\nfunction verifyMailgunSignature(\n timestamp: string,\n token: string,\n signature: string\n): boolean {\n const signingKey = process.env.MAILGUN_WEBHOOK_SIGNING_KEY ?? '';\n const value = timestamp + token;\n const hash = crypto\n .createHmac('sha256', signingKey)\n .update(value)\n .digest('hex');\n return hash === signature;\n}\n\napp.post('/webhooks/mailgun/inbound', (req: Request, res: Response): void => {\n const { timestamp, token, signature } = req.body as {\n timestamp: string;\n token: string;\n signature: string;\n };\n\n // Always verify the webhook signature to prevent spoofing\n if (!verifyMailgunSignature(timestamp, token, signature)) {\n res.status(401).json({ error: 'Invalid signature' });\n return;\n }\n\n const sender = req.body['sender'] as string;\n const subject = req.body['subject'] as string;\n const bodyText = req.body['body-plain'] as string;\n const recipient = req.body['recipient'] as string;\n\n console.log(`Inbound email from ${sender} to ${recipient}: ${subject}`);\n console.log('Body:', bodyText.slice(0, 200));\n\n // Process the email (e.g., create a support ticket)\n // ...\n\n // Mailgun expects a 200 response to acknowledge receipt\n res.status(200).json({ status: 'received' });\n});\n\napp.listen(3000, () => console.log('Webhook server running on port 3000'));",
69
+ "notes": "Configure inbound email routing in the Mailgun dashboard under Receiving > Routes. The signing key for webhook verification is different from the API key — find it under Settings > Webhooks. Always verify the signature to prevent spoofed webhook requests."
70
+ }
71
+ ],
72
+ "gotchas": [
73
+ "Mailgun API keys have a region-specific endpoint: US accounts use api.mailgun.net, EU accounts must use api.eu.mailgun.net. Using the wrong endpoint returns an authentication error with no helpful 'wrong region' message. Check your account region in the Mailgun dashboard under your domain settings.",
74
+ "Mailgun's free 3-month trial restricts sending to sandbox subdomains (sandboxXXXXXX.mailgun.org) — you cannot send to arbitrary addresses. You must add and DNS-verify a custom domain to send to real customers. Sandbox domains are for testing only and will not work in production.",
75
+ "The mailgun.js package requires form-data as a separate peer dependency in Node.js environments. In browser environments, the native FormData global is used automatically. Forgetting to install form-data results in a 'FormData is not defined' runtime error that can be confusing to debug.",
76
+ "Mailgun was acquired by Sinch in 2021. Some integrations (particularly older EU-hosted accounts) experienced billing and support disruptions during the transition. Platform stability has improved since, but the acquisition history is worth monitoring for any future ownership changes that could affect service continuity."
77
+ ],
78
+ "reliability": {
79
+ "uptimeGuarantee": "99.99% uptime SLA (Enterprise plan)",
80
+ "statusPageUrl": "https://status.mailgun.com",
81
+ "notes": "Globally distributed MTA infrastructure with redundant delivery paths. Standard and Foundation plans do not include a formal SLA. Enterprise plan includes 99.99% uptime guarantee and dedicated support. Inbound email processing (routing) has occasionally had higher latency during traffic spikes."
82
+ },
83
+ "qualityScore": 7,
84
+ "qualityJustification": "Solid transactional email API with excellent inbound email parsing — a unique strength compared to Resend and Postmark. The email validation API adds genuine value for list hygiene. Loses points for a confusing free tier structure (3-month trial vs Flex plan vs Foundation), region-specific endpoints that cause silent failures, the form-data peer dependency issue, and organizational uncertainty following the Sinch acquisition. Stronger than SendGrid on inbound parsing; weaker on developer experience than Resend.",
85
+ "alternatives": ["resend", "sendgrid", "postmark"],
86
+ "complementary": ["supabase", "stripe", "clerk"],
87
+ "bestFor": "Transactional email with inbound email parsing — receive, parse, and route incoming emails via webhook in addition to high-deliverability outbound sending",
88
+ "lastVerified": "2026-02-25",
89
+ "entryVersion": 1,
90
+ "addedBy": "claude-code-session-4"
91
+ }
@@ -0,0 +1,91 @@
1
+ {
2
+ "name": "Postmark",
3
+ "slug": "postmark",
4
+ "category": "email",
5
+ "subcategory": "transactional-email",
6
+ "website": "https://postmarkapp.com",
7
+ "description": "Postmark is a transactional email provider laser-focused on deliverability and speed. Unlike platforms that mix transactional and marketing email on shared infrastructure, Postmark uses dedicated IP pools solely for transactional traffic, resulting in industry-leading inbox rates.",
8
+ "useCases": [
9
+ {
10
+ "task": "Send transactional emails with the highest possible deliverability",
11
+ "fit": "perfect"
12
+ },
13
+ {
14
+ "task": "Send password reset and account notification emails",
15
+ "fit": "perfect"
16
+ },
17
+ {
18
+ "task": "Track email opens and clicks with detailed analytics",
19
+ "fit": "good"
20
+ },
21
+ {
22
+ "task": "Send bulk marketing campaigns",
23
+ "fit": "partial"
24
+ }
25
+ ],
26
+ "auth": {
27
+ "method": "api_key",
28
+ "setupSteps": [
29
+ "Sign up at postmarkapp.com",
30
+ "Create a Server (each server has its own API token)",
31
+ "Go to the server's API Tokens tab",
32
+ "Copy the Server API token",
33
+ "Verify your sending domain under Sender Signatures or Domains",
34
+ "Set POSTMARK_API_TOKEN environment variable"
35
+ ],
36
+ "envVarName": "POSTMARK_API_TOKEN",
37
+ "codeSnippet": "const client = new postmark.ServerClient(process.env.POSTMARK_API_TOKEN!);"
38
+ },
39
+ "pricing": {
40
+ "model": "freemium",
41
+ "freeTier": "100 test emails/month (in sandbox mode only)",
42
+ "startingPrice": "$15/month for 10,000 emails",
43
+ "costPer": "$1.50 per 1,000 emails ($0.0015/email) on pay-as-you-go",
44
+ "pricingUrl": "https://postmarkapp.com/pricing"
45
+ },
46
+ "rateLimits": {
47
+ "tier": "all tiers",
48
+ "limit": "No documented hard rate limit; burst up to 300 messages/second on high-volume plans",
49
+ "notes": "Postmark focuses on quality over quantity. Throughput scales with plan. The sandbox server has separate rate limits.",
50
+ "retryStrategy": "Implement exponential backoff for 429 and 5xx responses; check X-Postmark-Rate-Limit-Limit header"
51
+ },
52
+ "sdk": {
53
+ "primaryLanguage": "typescript",
54
+ "installCommand": "npm install --save-exact postmark",
55
+ "importStatement": "import * as postmark from 'postmark';",
56
+ "otherLanguages": ["python", "ruby", "java", "php", "csharp", "go"]
57
+ },
58
+ "codeExamples": [
59
+ {
60
+ "title": "Send a basic email",
61
+ "language": "typescript",
62
+ "code": "import * as postmark from 'postmark';\n\nconst client = new postmark.ServerClient(process.env.POSTMARK_API_TOKEN!);\n\nconst result = await client.sendEmail({\n From: 'noreply@yourdomain.com',\n To: 'user@example.com',\n Subject: 'Password Reset',\n HtmlBody: '<h1>Reset your password</h1><a href=\"{reset_url}\">Click here</a>',\n TextBody: 'Reset your password: {reset_url}',\n MessageStream: 'outbound',\n});\n\nconsole.log('Message ID:', result.MessageID);",
63
+ "notes": "Always include both HtmlBody and TextBody for best deliverability. The 'From' must be a verified sender signature."
64
+ },
65
+ {
66
+ "title": "Send with a template",
67
+ "language": "typescript",
68
+ "code": "import * as postmark from 'postmark';\n\nconst client = new postmark.ServerClient(process.env.POSTMARK_API_TOKEN!);\n\nconst result = await client.sendEmailWithTemplate({\n From: 'noreply@yourdomain.com',\n To: 'user@example.com',\n TemplateAlias: 'password-reset',\n TemplateModel: {\n username: 'Jane',\n reset_url: 'https://app.com/reset/abc123',\n product_name: 'MyApp',\n },\n MessageStream: 'outbound',\n});\n\nconsole.log('Sent with template, ID:', result.MessageID);",
69
+ "notes": "Templates are managed in the Postmark dashboard. Use TemplateAlias (not ID) for maintainability."
70
+ }
71
+ ],
72
+ "gotchas": [
73
+ "Postmark separates 'transactional' and 'broadcast' (marketing) streams with different API endpoints and infrastructure. Using the outbound stream for marketing email violates their terms and can get your account suspended.",
74
+ "The free sandbox mode is separate from production — test emails go to a test inbox, not real recipients. Switch to your live Server API token for actual delivery.",
75
+ "Postmark is significantly more expensive than SendGrid/Resend at high volumes. It is optimized for deliverability, not price. Calculate your actual cost before committing.",
76
+ "Sender signatures must be individually verified (each from-address needs its own verification, unless you verify the full domain)."
77
+ ],
78
+ "reliability": {
79
+ "uptimeGuarantee": "99.99% uptime SLA",
80
+ "statusPageUrl": "https://status.postmarkapp.com",
81
+ "notes": "Postmark is known for consistently fast delivery (median under 3 seconds) and high inbox rates. They publish detailed deliverability statistics publicly."
82
+ },
83
+ "qualityScore": 8,
84
+ "qualityJustification": "Best deliverability in the industry with excellent TypeScript SDK and honest, transparent practices. Slightly more expensive and more complex setup than Resend. The strict separation of transactional/marketing streams is a feature, not a bug.",
85
+ "alternatives": ["resend", "sendgrid", "mailgun"],
86
+ "complementary": ["stripe", "clerk"],
87
+ "bestFor": "Transactional email where deliverability is the #1 priority and cost-per-email is secondary",
88
+ "lastVerified": "2026-02-25",
89
+ "entryVersion": 1,
90
+ "addedBy": "claude-code-session-1"
91
+ }