Private forms
Every form is open by default: anyone with the public slug can submit to it, no credentials needed. That's what you want for a contact form embedded on a public site.
Sometimes you want the opposite, only your own server should be able to post to it. That's what access keys are for.
The public slug isn't a secret
The ID in your submission URL (/f/{public_slug}) is meant to be seen. It's
fine to hardcode it into HTML anyone can view the source of.
On its own it only lets someone submit to that form, it can't read submissions, list your forms, or change settings.
Making a form private
Switch a form to protected mode in its settings and it will only accept submissions carrying a valid access key. Reach for this when:
- Only your own backend should be able to post (server-to-server, never touching the browser)
- You're building an internal tool where "anyone with the URL can submit" is not acceptable
An access key looks like this, and it's shown to you exactly once, at creation time:
fp_live_9a3f2c1e_R2VuZXJhdGVkIGJ5IEZvcm1QbHVtZQForm Plume only ever stores a hashed version (Argon2id) of it, so it can't be recovered later, only rotated. Treat it like a password: keep it out of client-side JavaScript and out of your repo.
Send it as a bearer token on every request:
curl https://api.formplume.com/f/{public_slug} \
-H "Authorization: Bearer fp_live_..." \
-d "email=lead@example.com" \
-d "message=Hello"A query param (?access_key=...) and a form field (access_key) both
work as fallbacks, in case your HTTP client makes custom headers awkward.
Prefer the header where you can: query strings and form bodies are more likely to end up in logs.
A protected form that gets a request without a valid key responds
401 Unauthorized. See Success and errors for the full response shape.
Access keys vs. dashboard login
Logging into the dashboard to view submissions or manage forms is regular
session-based login, not access keys. Access keys exist only to guard the
/f/{public_slug} submission endpoint.