Where
Web Forms→Install
Your role needs
Read access to Web form capture endpoint
read-web-forms. Admin, Member and Viewer have it by default.To create
create-web-forms on top of the permission above.Endpoint
They live at
https://api.pipelime.ai. {token} is the one credential they check. There’s no API key and no Authorization header, so treat the URL itself as the secret.
The capture script uses both paths. A direct integration (your own code, a Zapier zap, a platform’s native webhook) only ever needs the submissions route. See Install methods: JavaScript snippet or direct endpoint for the script tag itself and the platform-specific guides.
Request body
A checkbox group or a multi-select has to arrive as one value, not an array: join the selected options into a single string before you send them. A
fields value that’s an array or an object instead of a scalar, a field name that’s too long, or a value that’s too long all fail validation the same way; see Responses.
A form_key is matched on the key alone. Nothing else about the definition is looked at. Send one that doesn’t match anything, or leave it out entirely, and the submission is queued exactly the same way; what decides whether it becomes a lead automatically, or waits in the product for you to map it, is on Field mapping and the submissions inbox.
Every context key is an optional string, and only the keys below are read. Anything else you put in context is accepted and then ignored:
The domain check
A request that carries anOrigin or Referer header is checked against the form’s configured domain: Origin when both are there. A request with neither is treated as server-to-server and let through on the strength of the token alone.
Only hostnames are compared. The host is read out of the header value (so the scheme and any port are dropped), lowercased, and a leading
www. removed. The form’s configured domain is normalised the same way: scheme, leading www. and any trailing slash come off first. A form saved as https://www.acme.test/ therefore matches a page served from https://acme.test/contact.
The
OPTIONS preflight always answers 204, even for a token that doesn’t resolve to a form. So an unknown token doesn’t get blocked at this stage; the actual POST still goes through and comes back with the real 404 your JavaScript can read. A domain mismatch is different: the preflight for a token it does recognize carries that form’s own domain in its CORS header, not the calling page’s, so the browser refuses to send the POST at all. You’ll see a CORS failure in the console, never a 403: only a server-to-server call, which skips preflight entirely, gets that body directly.404. There’s no way to tell “wrong token” from “this form is turned off” from the response alone.
Responses
Every response from the submissions route:
The checks run in that order: token, then domain, then body size, then validation. The first one that fails is the response you get.
Two different problems both come back as
{"error": "Invalid payload"}. One is Laravel’s own validator failing. That one also carries an errors object naming the field. The other is a fields value that isn’t a plain scalar, or a name or value that’s too long, checked separately after the validator passes. It never gets an errors object. Check whether errors is present before assuming which one happened.Honeypot and deduplication
Two things stop a submission before it is ever queued for processing, and they stop it in different ways:_hpis a honeypot: real visitors leave it empty. Any value in it that isn’t blank marks the submission spam. The submission is still recorded, with that status, but nothing is queued.- The exact same
fieldssent again from the same IP address, to the same form, shortly after the first attempt doesn’t create a second submission. Nothing new is stored at all. Onlyfieldsis compared, so a differentcontexton the retry (a different page, different UTM tags) doesn’t change that.
200 {"status": "accepted"} as a genuine success, so neither a spam script nor a retried request can tell it was caught.
Form discovery
The capture script also reports the forms it finds on a page to/api/public/web-forms/{token}/forms: their fields, labels and how each one submits. We use that to build the list you map fields against in the product. A successful report answers 200 with {"status": "ok"}. A direct integration doesn’t need to call this route at all, unless it’s replicating what the script does.
The token check, the domain check and the size limit are the same as on the submissions route. Posting a form’s key again refreshes what’s known about its fields, but never touches whether you’re tracking it or how its fields are mapped. Rediscovery can’t downgrade a form you’ve already set up.
Rate limit
Requests to this endpoint are throttled on their own, keyed by IP address and form token together: a different address posting to the same form, or the same address posting to a different form, each has its own budget. The submissions route and the discovery route share that budget: discovery calls from one address eat into what’s left for submissions from that same address. Go over it and further calls return429 until the window clears.
Related
Install methods: JavaScript snippet or direct endpoint
The exact script tag, the platform-specific guides, and the context fields each install method accepts.
Connect the forms on your website
Scan your site, map the fields, and turn on the form this token belongs to.
API overview
Where this endpoint sits next to the versioned lead-intake API.