The example
The Bridge admin console generates this block already filled in with your workspace’s values. The version below uses placeholders so you can read it before you have them. Replace the form markup and the consent wording with your own. The script underneath only needs to change if your field ids differ from the ones used here.Your capture key is not an API key
If you have read the Authentication page, it tells you never to put a key
in frontend code. That rule is about the Integrations API key, and it still holds. Your
captureKey is a different kind of value.x-api-key used by the Integrations API, your captureKey is designed to live
in your page’s HTML where anyone can read it. It grants no read access to anything: it only
identifies which workspace a submission belongs to. Abuse is bounded by two other checks —
the reCAPTCHA token, and the fact that submissions are only accepted from the domains
registered for your workspace.
Never use your Integrations API key here, and never put one in a page.
Put the workspace id on the URL
The workspace id goes in the request body and on the URL as?workspaceId=.... It has
to be in both places: a browser sends a CORS preflight before the real request, and that
preflight carries no body — so without the id on the URL we cannot tell which workspace you
are, cannot return the header that authorises your domain, and the browser blocks the
request before it is ever sent.
The failure this causes is confusing, which is why it is worth getting right the first
time: you will see a CORS error in the browser console and no request in our logs at all,
because the real request never left the page.
Mint the captcha token when the form is submitted
A reCAPTCHA v3 token is valid for about two minutes. Minting it when the page loads means it is often already expired by the time somebody finishes typing, and it comes back rejected — as a403, which looks like a permissions problem rather than a timing one.
Mint a new token for every attempt
A token verifies exactly once. If a submission fails and you retry with the same token, the replay is indistinguishable from an attack and returns the same error a bot would get. Always callgrecaptcha.execute again before retrying.
What to send
The endpoint reference carries the full contract. These are the fields whose meaning is not obvious from the schema alone:string
The brand your landing page sells — not a line, channel or phone number id. Required only
if your workspace has brands enabled. A line id is never required.
string
The page’s origin and path, without the query string. Your UTMs travel separately in
utm, and a raw query string often carries click ids or session tokens that should not be
stored. Send https://example.com/offer, not https://example.com/offer?gclid=....object
Your attestation that the visitor opted in, and when. See
Consent requirements — the wording on your form is not optional.
object
Collected from the query string against an allowlist:
utm_* parameters plus any extra
names you configure in the console. This is an allowlist rather than a denylist on
purpose — over-collecting here is not reversible.After you submit
A202 means the lead was accepted and queued. It does not mean a message was sent —
that happens later, in a separate service. Tell the visitor you will message them shortly.
Anything else is an error. See the error reference for what each one
means and whether it is yours to fix.