Skip to main content
This guide takes you from a new Console account to a verified human on your own page. You create a site key and a development gate, add the <botshield-verify> widget, handle its success event, and confirm the result on your server. Development is not billed.

Before you start

  • A BotShield Console account. Sign up at console.botshield.ai.
  • A BotShield ID, so you can complete a verification yourself. The quickest way is app.botshield.ai (public beta): create a passkey and confirm in the browser, no download. The BotShield app for iPhone and Android is optional and in review. See Testing.
  • A page you can edit and a server endpoint you can add.

The flow

Build it

1

Create a site key

In the Console, set the environment toggle in the page header to Development. Open Settings → Developer Tools → Site Keys and select New Site Key.Copy the public key. A development site key starts with pk_test_. Add your site’s origin (for example https://shop.example.com) to the key’s allowed origins. localhost is always allowed for pk_test_ keys. A pk_live_ key must list at least one origin.A site key is public. It is safe in your page source because it only works from its allowed origins.
2

Place and activate a gate

Open BotShield Gate and select Place a gate. Give it a name and a key, choose the Human gate type, and choose a verification mode:
  • Recent Presence: returning humans pass instantly.
  • Live: every verification asks for a new biometric confirmation.
The gate’s key is the value you put in the widget’s scope attribute. It is case-sensitive.Placing a gate creates a Draft. A draft does not answer verifications. Open the gate and select Activate. See Place a gate for the full lifecycle.
3

Add the widget to your page

Load the script once, then place the element where the user takes the action. This example uses the mock brand Meridian Airlines and a gate with the key checkout.
scan-mode="modal" names the widget’s flow, and it is the default. On desktop the widget shows a QR code for the user to scan with their phone. On a phone it opens the BotShield app directly. The embed snippet in the Console includes the attribute.
(scope is the embed attribute for the gate key.) See Web component for every attribute, event, and method.
4

Handle botshield:success

The widget dispatches botshield:success on the element when the human is verified. The event bubbles, so you can also listen on a parent.
event.detail has two shapes you must handle:On botshield:failure, offer the user another way forward. Do not treat it as proof of a bot. See Result states.
5

Verify on your server

Never trust the browser event on its own. When you have a token, send it to POST /sdk/verify-token. The endpoint needs no API key, because the signed token is the proof.
(census is the API’s name for BotShield Gate.) A valid token returns:
An invalid or expired token is a normal result, not an error:
Allow the action only when all of these hold:
  • valid is true and claims.verified is true.
  • claims.organization_id is your organization. Copy your Organization ID from Settings → Developer Tools → API Keys in the Console. POST /sdk/create-session also returns it as organization.id.
  • You have not already accepted this request_id. The token lives 120 seconds and verify-token does not consume it, so record each request_id and reject repeats.
The SDK returns the same fields in camelCase (requestId, organizationId) and does not unwrap the envelope. Read result.data.data and check result.data.error first.
6

Handle the Recent Presence case

An instant pass happens only on a Recent Presence gate, and only when you identify the user to the widget with the platform-user-ref attribute and BotShield recognizes them from an earlier verification on your site. See BotShield ID. The sample above does not set platform-user-ref, so it always returns a token.When token is null, there is nothing to pass to verify-token. Look the request_id up from your server instead.
verification/status returns its payload directly under data, not under data.data.
An instant pass is recorded with status: "pass", not "completed". Accept either value as Verified, and never test for "completed" alone. The instant-pass record reads "expired" 60 seconds after the check, so look it up as soon as your page reports success. If it is already "expired", ask the user to verify again. No webhook is sent for an instant pass.
If you want a signed token on every verification, set the gate’s verification mode to Live. Live gates always ask for a new confirmation and always return a token.

Server-to-server instead

You can run the whole flow from your server with an API key: create a grant token, create a verification link, send the user to it, and read the result from a webhook or GET /verification/status. Use this when you cannot embed the widget, for example in a native app or an email link. See Verify on your server.

Next steps

Web component

Every attribute, event, and method on <botshield-verify>.

Verify on your server

Token verification, local JWKS verification, and the server-to-server flow.

Webhooks

Receive gate.human_verified and gate.unavailable on your endpoint.

Keys and environments

Site keys, API keys, and moving from Development to Production.