← All work

Contact form backend
Spam resistance without exposing secrets

A contact API that keeps your inbox clean and your credentials safe: your email address stays off the page so harvesters never see it, automated spam is blocked before it reaches you, and every submission is validated and stored before delivery, all without putting sensitive configuration anywhere near the browser.

TypeScriptFastifyALTCHAPostgreSQLCORS

Clear RESTful contract for the frontend

Two endpoints keep responsibilities obvious: fetch a challenge, then post the form with a signed solution.

Case study 1 · How the frontend connects

Challenge and submit flow

End-to-end flow: challenge, local solve, verified submit, then persist and SMTP delivery; credentials never reach the browser.

What it does

GET /challenge returns a signed challenge the client solves before submit. POST /contact accepts JSON with name, email, subject, body, and the ALTCHA payload. After verification the service stores the row and sends a plain-text notification to the company inbox using the form subject line; the visitor's name, email, and message appear in the body (there is no separate Reply-To header; reply using the address in the text).

What the frontend sends

POST /contact
Content-Type: application/json

{
  "name": "Alex Visitor",
  "email": "visitor@example.com",
  "subject": "Project inquiry",
  "body": "Message text…",
  "altcha": "<signed solution from client>"
}

Why this matters for your product

The marketing app stays static-friendly while sensitive configuration lives only on the server, easier to rotate keys, swap providers, and greatly reduce spam.

Validation and safe failure modes

Structured validation, minimum lengths, and sanitization before any database write or mail send, so bad input fails fast without leaking internals.

Case study 2 · Spam protection

Input handling and ALTCHA verification

What it does

Request bodies are validated with explicit rules: required fields, minimum lengths (for example name and subject/body floors after trim), @IsEmail() on the address, and sanitization that strips null bytes and most C0 control characters while keeping newlines, tabs, and carriage returns. The ALTCHA payload is verified with the shared secret before any insert or outbound mail.

What makes it valuable

  • Proof-of-work reduces automated spam without a third-party captcha UI dependency on every page
  • Predictable JSON errors for validation and ALTCHA failures; operational issues surface as generic 4xx messages to the client
  • CORS restricted to a configured origin for browser calls

Why this matters for your app

Public endpoints are where small oversights become incidents. This pattern keeps the happy path fast and the unhappy path boring.

SMTP delivery, persistence, and auto-reply

Nodemailer with environment-driven SMTP settings; verify the transporter before send; persist every submission; gate the submitter confirmation when the same address is sending too often.

Case study 3 · Delivery & reliability

Nodemailer SMTP and submission pipeline

Persist first, notify the company inbox over SMTP, then optionally send the templated confirmation, gated so repeat senders do not get spammed.

What it does

Every accepted submission is inserted into PostgreSQL (Drizzle ORM) before mail leaves the process. Outbound mail uses nodemailer with environment-driven SMTP settings and receives the notification. The transporter is verified before send so misconfiguration fails loudly at startup or first delivery. An optional confirmation to the submitter uses message, subject, and signature. That auto-reply is skipped when backoff applies (for example three or more submissions from the same email today, or another submit within the past hour), the company notification still sends and the API can still return success.

What makes it valuable

  • Durable record of inbound interest alongside deliverability (audit trail, support, and abuse review)
  • SMTP verify-before-send catches bad credentials early
  • Company notification and gated auto-reply stay in one mail module with clear environment boundaries

Why this matters for your app

Contact endpoints sit on the public internet: pairing persistence with conservative auto-reply behavior reduces spam to your users while keeping your team informed.

How we work

Tight scope, explicit contracts, and shipping code you can operate.

1

Shape

Define endpoints, payloads, and what “done” means for security and deliverability.

2

Harden

Validation, configuration boundaries, and logging that helps you debug without exposing secrets.

3

Integrate

Wire the frontend or static site to the API and verify end-to-end in a realistic environment.

4

Hand off

Document env vars and runbooks so your team can own the service long term.

Backend and API work

A fit when you need a focused service: contact pipelines, webhooks, or JSON APIs with TypeScript, clear validation, and deployment-friendly configuration.

Node.js / FastifyTypeScriptSecurity-minded defaultsEmail integrations

Contact us to discuss APIs, integrations, or hardening an existing endpoint.