Platform
Hosting & deploysPush to a branch, get a live linkDatabaseReal Postgres, one per appSign-inEmail and Google, users includedFile storageUploads, photos and documentsPaymentsCheckout and plans, same projectAI gatewayEvery model, with a hard spend cap
Solutions
Moving an app overFrom Lovable, Bolt, Replit or v0Your first real appNever shipped anything beforeSide project → businessWhen people start paying youPricingFrom $25/month plus prepaid credits
Resources
DocsGuides written for people who are newFor AI agentsClaude Code, Cursor, MCP, JSON CLIChangelogWhat shipped, most recent firstComponentsPaste-ready UI for sign-in and moreSupportA person answers, not a queue botRefer a friendBoth of you get credits Get started
Open in ChatGPT Open in Claude Last updated 2026-10-07

Forms

Point an HTML form at a Camplax URL and submissions land in the console — stored, spam-checked and optionally emailed to you. No backend to write.

A form endpoint is a public address that accepts form posts and keeps what they send. You create one per form — a contact form, a waitlist, an order enquiry — and set it as the form's action. There is nothing to deploy and no key to paste.

The two-minute version

In the console's Forms page, create an endpoint named after the form. It answers with a URL:

https://camplax.dev/v1/forms/frm_…

Point your form at it:

<form action="https://camplax.dev/v1/forms/frm_…" method="post">
  <input name="name" required>
  <input name="email" type="email" required>
  <textarea name="message"></textarea>
  <button>Send</button>
</form>

That is the whole integration. Submissions show up in the endpoint's inbox under Forms — newest first, unread ones marked — and the visitor is redirected to your redirectUrl when you've set one (a JSON caller gets {"ok": true} instead of the redirect).

The URL is public by design — it sits in your page's markup, like a Netlify form. It is unguessable, not secret: anyone who can read your HTML can submit to it, which is exactly what a form is for. Spam protection lives on the endpoint (rate limits and optional captcha), not on the URL.

Posting with fetch

JavaScript submits get a JSON answer:

const res = await fetch("https://camplax.dev/v1/forms/frm_…", {
  method: "POST",
  headers: { "Content-Type": "application/json", Accept: "application/json" },
  body: JSON.stringify({ fields: { email, message } }),
});
const { ok } = await res.json();

A POST whose Accept header asks for JSON always answers {"ok": true} (or an error); a plain browser post follows the redirect. application/x-www-form-urlencoded and application/json both work — send files elsewhere, forms keeps text fields only.

Limits and spam rails

Submissions are public intake, so they are fenced:

  • 20 posts per hour per visitor (by IP) and 60 per hour per endpoint — past that the answer is 429.
  • Up to 50 fields, each value capped at 16 KB, the whole submission at 64 KB — past that, 413.
  • cf-turnstile-response — when the endpoint has captcha on, posts must carry a Turnstile token solved on your own site (see below) or they are refused with 403.

A submission that passes the rails is written first; anything after that — the notify email — can fail without ever losing the post.

Captcha

Turn captcha on per endpoint in the console. Your site then renders a Turnstile widget inside the form with the project's site key — the console shows it next to the endpoint once captcha is on, and it is the same key the sign-in bot check issues:

<form action="https://camplax.dev/v1/forms/frm_…" method="post">
  …
  <div class="cf-turnstile" data-sitekey="0x4AAAA…"></div>
  <script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async></script>
</form>

The token is verified against the hostname it was solved on, so a token from someone else's site never passes in yours. Captcha needs the form to live on a host the project serves — its *.camplax.app address or one of its custom domains.

Notify email

Set notifyEmail and every submission is mailed to that address: the fields, a link to the inbox. The address is whatever the project's owner typed — Camplax never stores it anywhere but the endpoint row.

Reading submissions from your app

The inbox is console data, but an app can read it with the CAMPLAX_PROJECT_TOKEN it already has (scope forms:read — the injected token picks it up on its next deploy):

GET /v1/projects/<slug>/forms/<endpoint id>/submissions
Authorization: Bearer $CAMPLAX_PROJECT_TOKEN

Answers newest-first, up to 1,000:

{ "submissions": [ { "id": "sub_…", "fields": { "email": "…", "message": "…" }, "ip": "…", "ua": "…", "createdAt": "…", "readAt": null } ] }

Submissions carry the sender's IP and user agent as received — use them for spam judgement, not display.

Managing endpoints

In the console: Forms lists every endpoint with its counts; a row opens its inbox and settings. The same surface over the API, with your console session:

MethodPathWhat it does
GET/v1/projects/<slug>/formsList endpoints with submission counts
POST/v1/projects/<slug>/formsCreate — { name, notifyEmail?, redirectUrl?, captcha? } → { key, url }
PATCH/v1/projects/<slug>/forms/:idEdit name, notify address, redirect, captcha, or switch off with { "enabled": false }
DELETE/v1/projects/<slug>/forms/:idDelete the endpoint and its inbox
GET/v1/projects/<slug>/forms/:id/submissionsThe inbox, newest first (also forms:read app keys)
POST/v1/projects/<slug>/forms/:id/submissions/:sid/readMark read; { "read": false } marks unread

A project can have up to 25 endpoints. An endpoint switched off answers 404 — to the outside world it does not exist.

© 2026 Camplax From $25 / month · credits stop at zero
Ask about Camplax