Skip to main content

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.
Unlike the 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 a 403, 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 call grecaptcha.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=....
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

A 202 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.