Skip to main content
botshield-sdk is the typed TypeScript client for the BotShield API. Use it on your server to confirm BotShield Gate results, and in your agent to ask a human to Confirm or Deny an action. It covers the same operations as the HTTP API and adds types, optional retries, timeouts, and a built-in MCP server. This page describes version 2.0.1.

Install

Requirements

  • A runtime with ECMAScript 2020, the Fetch API, and Web Streams: Node.js 18 or 20 LTS, Bun 1 or later, Deno 1.39, or an evergreen browser. The built-in MCP server needs Node.js 20 or later.
  • The package ships ESM and CommonJS builds. Its runtime dependencies are zod and @modelcontextprotocol/sdk.
  • For TypeScript, use "target": "es2020" or higher and include "dom" in lib so the fetch types resolve.
Use the SDK with secret keys on your server only. Never ship an API key or an agent key in browser code. In the browser, use the web component with a site key.

Create the client

Always set serverURL. The package’s default server is a local development address (http://localhost:9991/operations). A client created with new BotShield() and no options sends your requests to localhost and fails to connect. Pass serverURL: "https://api.botshield.ai/operations", or serverIdx: 1, which selects the same URL.
Client options:

Authentication

Include the Bearer prefix yourself. The SDK sends the value you give it as the Authorization header exactly as written, and the API reads credentials only from Authorization: Bearer <credential>. Pass `Bearer ${key}`, not the bare key. A bare key returns data.error with statusCode 401.
The two products authenticate differently. BotShield Gate: per call. Gate methods take a security object as their first argument. This lets one client use an API key for createSession and then the grant token for createVerificationLink. Agents Ask: on the client. Set the agent key once and the actions methods use it.
The client security type also lists agentKeyAuth1, and the security types of verifyToken, getStatus and getPartnerConfig list apiKeyAuth1. They are duplicates produced by the code generator. Ignore them.

Namespaces and methods

(census is the SDK’s name for BotShield Gate.) Every method also accepts a final options argument for per-call timeoutMs, retries, retryCodes, serverURL, and standard fetch options such as signal. Not in 2.0.1: the link operations (POST /agent/bind-session, GET /agent/check-binding) and the Age Gate response fields (gate_type, age_threshold, age_verdict, age_source). The SDK drops fields it has no type for, so call the HTTP API directly for those. See Link a human and Age Gate.

The response envelope

The SDK returns the API’s envelope as it is. It does not unwrap it and it does not throw on handler errors.
  • Request and response fields are camelCase in the SDK (anchorGrantToken, requestId). The SDK converts them to and from the API’s snake_case. Timestamps arrive as Date objects.
  • Read the result from result.data.data. For verification.getStatus and census.logout, read it from result.data.
  • Check result.data.error first. A rejected request resolves normally with result.data.error set to { message, statusCode, code? }.
Only real HTTP errors throw. See Errors.

BotShield Gate: confirm a widget result

Most integrations place the web component on the page and confirm the result on the server. Your page sends the request_id and token from the widget’s success event to your server, and your server runs this check before it unlocks the action.
POST /sdk/verify-token is open and the token has no audience claim, so the comparison of organizationId and requestId is what ties the token to your request. Do both.

BotShield Gate: create a request from your server

Use this flow when your server, not the widget, starts the verification, for example in a native app or a server-rendered step. The status can be completed or pass. Accept both.
A 409 comes back only while the same user (partnerUserRef, or the partnerUserId from createSession when you send no reference) has a pending, unexpired request for the same gate. A completed or failed request never blocks a new one. revokeVerification ends exactly those pending requests and reports the number in revokedCount. expiresAt is the request’s own expiry, five minutes after it was created. It is the same instant verification.getStatus returns as expiresAt, so it is the right deadline for your polling loop. The gate is looked up in your API key’s environment: a bs_dev_… key reaches the Development gate named checkout, and a bs_production_… key reaches the Production one. Requests you create this way count in the gate’s Overview and in Analytics in the Console, the same as requests the widget starts. Do not send userEmail. It is deprecated and ignored. webhookUrl is deprecated and has no effect, because webhooks are configured in the Console. See Webhooks overview. In the response, qrCodeUrl is deprecated and does not resolve to an image. Draw your own QR code from webUrl.

Agents Ask: propose an action and wait

Set the client timeoutMs above the long-poll window, or pass { timeoutMs: 35_000 } as the options argument on checkActionStatus. Verify resolutionJwt before your agent acts on it. See Proof of Resolution.

Standalone functions

Every method is also exported as a standalone function that takes a BotShieldCore client. Bundlers can tree-shake everything you do not import, which matters in serverless and edge bundles. Standalone functions return a Result instead of throwing.
The function names follow the pattern <namespace><Method>: censusCreateSession, censusCreateVerificationLink, censusVerifyToken, censusRevokeVerification, censusLogout, verificationGetStatus, actionsProposeAction, actionsCheckActionStatus, actionsCancelAction. Each lives in botshield-sdk/funcs/<kebab-case-name>.js.

Errors

There are two kinds of failure, and you need to handle both. Handler errors do not throw. They arrive as result.data.error with HTTP 200. This covers 401, 403, 404, 409, 422 and the other codes listed in Errors. HTTP and transport errors throw. Import the classes from botshield-sdk/models/errors:

Retries and timeouts

Retries are off by default. Turn them on for the whole client with retryConfig, or for one call with the retries option. Intervals are in milliseconds. The example in Errors shows both forms. Two things to know:
  • The retry codes do not include 403, so a rate-limited call is not retried. Catch it and wait as described in Rate limits.
  • Retries act on HTTP status only. A handler error inside an HTTP 200 response is never retried.
timeoutMs works the same way: set it on the client, or per call in the options argument. A call that times out throws RequestTimeoutError.

Run the SDK as an MCP server

The package includes a Model Context Protocol server that exposes the Agents Ask methods as tools for an MCP-capable agent host. It needs Node.js 20 or later.
Pass --server-url. Without it the server targets the local development address, the same default as the client. The --agent-key-auth value needs the Bearer prefix. Run npx -y --package botshield-sdk -- mcp start --help for all flags. The default transport is stdio. BotShield also hosts an MCP server that needs no local process and adds the link tools. See MCP server.

Error codes

result.data.error.code is a string, present when the API sets one. For the operations this SDK calls, the documented codes are ttl_below_floor and ttl_above_ceiling on actions.proposeAction. The error object then also carries minTtlSeconds or maxTtlSeconds. gate_not_active and gate_not_found are reported by the widget, as the reason of its botshield:failure event. See Web component. The SDK’s gate methods report a missing or inactive gate through message and statusCode, so branch on statusCode.

Coming in SDK 2.1

Version 2.0.1 is the current release. These changes arrive with BotShield 3.0 and are not in 2.0.1. Until 2.1 is published, the SDK drops fields it has no type for, so call the HTTP API directly when you need one of them.

Call the API without the SDK

The SDK is a thin layer over plain JSON operations. For other languages, or for the operations and fields the SDK does not cover, call the HTTP API directly. API overview has the base URL, the credentials, and the envelope, and Errors has a small typed fetch helper.

Upgrading

2.0.1

Released 25 September 2026, regenerated from the September API specification.

From 1.x

Version 2.0.x is a different generated client from 1.x. The API operations are the same. The calling conventions are not.

Next steps

Verify on your server

The full server-side check for a gate result.

Propose an action

Request fields and outcomes for Agents Ask.

Errors

Status codes for every operation.

Keys and environments

Create the keys this page uses.