Platform
Hosting & deploysPush to a branch, get a live linkDatabaseReal Postgres, one per appSign-inEmail and Google, users includedFile storageUploads, photos and documentsAI gatewayEvery model, with a hard spend cap
Resources
DocsGuides written for people who are newFor AI agentsClaude Code, Cursor, MCP, JSON CLICompareCamplax beside the stack it replacesPricingFrom $25/month plus prepaid creditsSupportA person answers, not a queue botPoliciesTerms, privacy and how we handle data Get started
Open in ChatGPT Open in Claude Last updated 2026-10-16

Widgets

Drop-in feedback, waitlist, changelog, inbox and chat widgets — a script tag on your page, endpoints already behind it.

Five small features that every app wants and nobody wants to build: a feedback box, a waitlist, a changelog, a per-user notification inbox, and a chat box. Each is a hosted script plus a public endpoint on the platform — the console's Widgets page hands you a ready-made snippet per widget.

Adding one

<script src="https://camplax.dev/cdn/feedback.js"
  data-project="<slug>" data-api="<api origin>"
  data-key="wx_…" data-turnstile-sitekey="…" data-screenshot></script>

Paste the snippet where the widget should live. Some widgets also need a mount point — <div id="camplax-waitlist">, <div id="camplax-changelog">, <div id="camplax-inbox"> — and the snippet says so. The data-key is your project's publication key: deliberately public, it only binds the embed to your project. Anonymous writes are protected the real way — the Origin must be a hostname that is live for your project, every action is rate-limited per IP, and each mutation needs an invisible Turnstile token the script obtains itself. That works on your custom domains too: on a page outside camplax.app the script asks GET /v1/w/<slug>/challenge for your project's own bot-check key, which Camplax issues and keeps in step with your domains (up to nine custom domains per project).

Server-side calls skip the publication key and send your app's own CAMPLAX_PROJECT_TOKEN as Authorization: Bearer … — Camplax injects it into every environment, so there is no key to create. (A project API key with widgets:read or widgets:write does the same from outside Camplax.)

The five

Feedback. A bug / idea / praise box with an optional 1–5 rating, email and screenshot. Entries land on the Widgets page and emit a $feedback event into analytics.

Waitlist. Email capture with a queue position. Optional double opt-in (the widget mails a confirm link that lands on a hosted confirm page), disposable-domain blocking, referral ids, and a showPosition switch. A confirmed join emits $waitlist_join.

Changelog. You write entries in Markdown on the Widgets page — publish and unpublish per entry — and the widget renders sanitized HTML from GET /v1/w/<slug>/changelog. Fifty entries per fetch.

Inbox. Per-user notifications. The sensitive part is done properly: your server mints a 15-minute per-user token with POST /v1/w/<slug>/inbox/access-token and { "user": "<id>" }, authenticated with its CAMPLAX_PROJECT_TOKEN (which never reaches the browser), and the script reads only that user's items with GET /v1/w/<slug>/inbox. Create notifications server-side with POST /v1/w/<slug>/inbox (user, title, optional body and href). Each preview has its own inbox: a preview's token only reads and writes the preview's notifications, never production's.

const res = await fetch(`${process.env.CAMPLAX_API_URL}/v1/w/${process.env.CAMPLAX_PROJECT_SLUG}/inbox/access-token`, {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.CAMPLAX_PROJECT_TOKEN}`, "Content-Type": "application/json" },
  body: JSON.stringify({ user: session.user.id }),
});
const { token } = await res.json(); // render as data-user-token on the inbox script

Chat. A visitor message box that stores threads — what a visitor sends lands on the Widgets page for you to read. It records the conversation; it sends no reply on its own — it is not yet a support agent.

There is also a dropzone script — file upload that uses the same signed upload-URL machinery as storage, bound to the size and type you allow, with active formats (SVG, HTML, JS) refused. Each upload is saved as a new file — its name gets a random prefix — so a visitor can never replace a file that is already there.

Settings and limits

Per project, in the console: chat options (collect email), waitlist options (double opt-in, show position, referrals, disposable block) and dropzone limits (max bytes up to 95 MB; bigger files go through a resumable upload, max files, accept list).

Public endpoints are rate-limited per action — feedback and waitlist joins at 5/hour per IP, chat at 8/minute, inbox reads at 60/minute. The full surface:

MethodPathCaller
POST/v1/w/<slug>/feedbackPublication key or production's app token
POST/v1/w/<slug>/waitlistSame — plus the hosted /waitlist/confirm link
GET/v1/w/<slug>/changelogPublication key or the app token
POST/v1/w/<slug>/chatPublication key or production's app token
GET/POST/v1/w/<slug>/inboxPer-user token, or the app token (each environment its own inbox)
POST/v1/w/<slug>/inbox/access-tokenThe app token only
POST/v1/w/<slug>/dropzone/upload-urlPublication key or production's app token
GET/v1/w/<slug>/challengeThe page itself — returns the bot-check key for its address

Feedback, waitlist, chat and dropzone keep production's data only, so a preview's token gets 403 preview_not_supported there; the scripts on a preview page still work with the publication key.

Under the hood: each script is a single-file bundle served from camplax.dev/cdn, and every write lands in platform tables owned by your project.

Camplax

Hosting, database, sign-in and storage in one project. One login, one bill.

Platform
More
Legal
Company
© 2026 Camplax From $25 / month · credits stop at zero