Skip to main content

Get Started with Your Form Backend

Four steps to a form endpoint of your own. Takes about 5 minutes.

Create a free account

30 seconds

Sign up with Google, GitHub, or email. No credit card required.

Install the CLI and create the project

2 minutes

Install the Codehooks CLI and scaffold the form backend template.

npm install -g codehooks
coho create myforms --template form-backend
cd myforms && npm install

Set the admin secrets and deploy

2 minutes

JWT_SECRET signs the admin session cookie and ADMIN_PASSWORD guards the login. The backend warns on startup if either is missing.

coho set-env JWT_SECRET "$(openssl rand -hex 32)" --encrypted
coho set-env ADMIN_PASSWORD 'choose-a-strong-password' --encrypted
coho deploy

# coho info shows your project URL

Create a form and point your HTML at it

Done!

Log in to get the admin cookie, create a form, and use the uuid it returns as the form action.

API=https://your-app.codehooks.io

curl -c cookies -X POST "$API/admin/login" \
  -H 'content-type: application/json' \
  -d '{"password":"your-admin-password"}'

curl -b cookies -X POST "$API/admin/api/forms" \
  -H 'content-type: application/json' \
  -d '{"name":"Contact"}'

# the response contains the form uuid

Then change one attribute

Drop the uuid into your existing form's action. A form with no field schema accepts whatever you send, so nothing else has to change.

<form method="POST"
      action="https://your-app.codehooks.io/f/YOUR-FORM-UUID">
  <input name="name" required>
  <input name="email" type="email" required>
  <textarea name="message"></textarea>
  <button type="submit">Send</button>
</form>

A browser post gets a 302 to your redirect URL, or to the hosted thank-you page at /thanks/<uuid> if you haven't set one. Send content-type: application/json and you get {"ok":true,"id":"..."} instead.

Restrict who can post to it

A new form has an empty allowedDomains, which accepts submissions from any origin. Add your site's hostname and the server checks the Origin header before it stores anything. Matching is exact on the full hostname, so list every hostname you actually submit from.

curl -b cookies -X PATCH "$API/admin/api/forms/<form _id>" \
  -H 'content-type: application/json' \
  -d '{"allowedDomains": ["www.example.com", "example.com"]}'

Accepting uploads? Set MAX_UPLOAD_MB to raise the per-request limit (it defaults to 5). Uploads are stored in your project's filestore and served only through the authenticated admin route, never a public one.

Want to see it working first? demo.formbackend.dev posts cross-origin to a live backend and shows you both the request and the response. Its source ships with the template in example/.

Ready to start?

Create your free account to get your API keys and start deploying.

Create Free Account

No credit card required. Free tier includes 500 API calls/day.

What ships in the template today:

One endpoint per formWorks without JavaScriptFile uploadsTyped validationDomain allowlistCSV export

Email notifications, outgoing webhooks, spam scoring and a visual dashboard are planned, and are not in this release.