Docs
Documentation

Let AI agents into your product, on your terms.

Turingate checks that a request comes from a real AI agent, tells you which verified person or company sent it and what they allowed it to do, and shares reputation across every site in the network. Most sites integrate in under 15 minutes with one API call.

Overview

AI agents such as Claude Code, Codex and shopping or travel assistants increasingly use websites and APIs on behalf of people. Today you can't tell a helpful agent from a scraper, so you either block them all and lose customers, or let them all in and invite abuse. Turingate gives each agent a short-lived, signed agent pass. Your server checks the pass, and you decide.

01Human authorizesA person signs a permission slip for their agent: scopes, spending limit, expiry.
02Agent proves itselfThe agent solves a fresh AI-only challenge for your site and signs it with its own key.
03Pass issuedTuringate issues a signed pass, valid only on your site and only for minutes.
04Agent calls youThe agent sends Authorization: AgentPass … with its request.
05You decideOne call to /v1/verify returns who it is, what it may do, and its reputation.

What you're buying: monthly agent passes, meaning verified agents admitted to your site, plus the verification API, the Console, the shared reputation network and the browser widget. Humans failing a challenge never count against you. See plans & quotas.

Quickstart: four steps

Create a site in the Console

Go to the Console, sign in with Google, and click Add site. You get a site ID (s_…, public) and an API key (rck_…, secret, shown once). Store the key as an environment variable such as TURINGATE_SITE_KEY. Never put it in browser code.

Tell agents your site ID

Agents need your site ID to request a pass that's valid for you. Return it automatically when a request has no pass (see Responding to agents), and add it to your llms.txt or API docs:

llms.txt

Verify passes on your server

Before acting on an agent's request, send its pass to POST /v1/verify with your API key, along with the action (scope) and amount it wants. One call returns valid, the reasons if it's refused, and the claims: who the agent works for, its verification tier and reputation.

Set your policy and report outcomes

Choose what to require: which scopes, maximum amounts, a minimum verification tier, a minimum reputation. Then report good or bad outcomes so the network learns. See Setting your policy and Reporting outcomes.

Core concepts

TermWhat it means
PrincipalThe person or company responsible for an agent. Has a signing key and an optional verification tier: 0 = key only, 1 = verified email, 2 = verified card.
AgentThe AI software acting for a principal (for example claude-code). Has its own signing key.
DelegationA permission slip signed by the principal: scopes (for example bookings:*), an optional spending limit, and an expiry (up to 30 days).
Agent passA signed token (EdDSA JWS) issued after the agent solves a challenge. It's bound to one site, expires within minutes, and is locked to the agent's key.
SiteYour website or API in the Console. Has a public site ID and a secret API key. Monthly quotas are counted per site.
ReputationA score built from outcomes reported by sites. Agents and principals that are reported for abuse get blocked across the network, including their verified email and card.

No-code: the agent desk

The agent desk is a hosted form that only AI agents can submit. Assistants send bookings, orders and questions for their users, and you receive each one with the agent's name and the verified person behind it. Human visitors are never affected: the desk is an extra lane, not a wall.

  1. In the Console, open your site, find Agent desk, and tick Accept requests from AI agents.
  2. Choose up to 8 fields (text, email, long text, number, date) and click Save.
  3. Share the desk link https://reverse-captcha.onrender.com/a/<site ID>, or paste the embed code the Console gives you.

Requests appear in the Console inbox. You can also have them emailed to you or sent to a webhook. Turn on Only agents with a verified owner for orders and anything involving money.

For agents: the desk API

GET /v1/forms/<site ID> describes the fields. To submit, get a pass for that site (for example with rc_get_challenge and site), then:

HTTP
POST /v1/forms/s_your_site_id
Authorization: AgentPass <pass>
Content-Type: application/json

{ "fields": { "name": "Ada Lovelace", "message": "Table for 2, Friday 8pm" } }
→ { "ok": true, "id": 42 }

Each pass can submit once. HTML form posts (application/x-www-form-urlencoded with an rc-pass field) are also accepted and redirect back with ?sent=1.

WordPress, Shopify & site builders

PlatformHow
WordPressInstall the Turingate plugin, paste your Site ID and API key under Settings → Turingate, and add [turingate_agent_desk] to a page. Requests appear under Agent requests in WordPress. Optionally verify Authorization: AgentPass on your REST API and WooCommerce checkout, which checks the owner's spending limit.
ShopifyAdd a "For AI assistants" menu link to your desk URL, or add our theme section under Edit code → Sections.
Webflow, Wix, Squarespace, FramerPaste the embed code from the Console into an Embed, Custom code or Code block.
CloudflareDeploy the Turingate Gate worker in one click. It verifies agent passes on the paths you choose and sends your origin X-Turingate-Agent, X-Turingate-Owner and X-Turingate-Tier headers.
Any websiteLink to your hosted desk from your menu, footer or llms.txt.

Webhooks, Zapier & Make

Set a Webhook URL on your agent desk and every request is POSTed to it as JSON within seconds. Use Send test in the Console to try it.

  • Zapier: trigger Webhooks by Zapier → Catch Hook, then any action (Google Sheets, Slack, Gmail, HubSpot…).
  • Make: Webhooks → Custom webhook.
payload
X-Turingate-Event: agent_form.submitted
X-Turingate-Signature: sha256=<hex HMAC-SHA256 of the raw body, keyed with your whsec_ secret>

{ "event": "agent_form.submitted", "site": "s_…", "site_name": "Bella Pizza", "id": 42, "at": "2026-11-13T10:00:00Z",
  "agent": { "name": "claude-code", "owner": "Ada Lovelace", "owner_tier": 1, "verified_owner": true, "solve_ms": 5400 },
  "fields": { "name": "Ada Lovelace", "message": "Table for 2, Friday 8pm" } }

To check a delivery came from Turingate, compute HMAC-SHA256(secret, raw body) and compare it with the signature using a constant-time comparison. Webhook URLs must use https:// and can't point at private networks. Deliveries time out after 5 seconds and don't follow redirects.

Verify a pass

POST /v1/verify, authenticated with the X-Site-Key header.

FieldTypeDescription
tokenstringThe pass from the agent's Authorization: AgentPass <token> header. Required.
scopestringThe action the agent wants, for example bookings:create. Must be within the delegated scopes (bookings:* covers it).
amountnumberMoney the action involves. Must not exceed the delegated spending limit. Omit it, or send 0, for actions without money.
currencystringOptional ISO code. If given, it must match the delegation's currency.
minTiernumberMinimum principal tier: 1 = verified email, 2 = verified card.
requireBoundbooleanReject anonymous widget passes. Automatic whenever scope, amount or minTier is set.
walletstringFail unless the agent's owner linked this wallet. Use it to check that a crypto payment came from the owner.

The response is always HTTP 200 with a verdict, unless your API key is wrong (401):

response

Common reasons: token expired, bad signature, pass was not issued for this site, scope "x" not delegated, amount N exceeds delegated limit, principal tier N is below required M, agent or principal blocked since this pass was issued.

Tip: passes last up to 10 minutes and can be checked as many times as needed while they're valid. Only issuing a pass counts toward your quota; verifying doesn't.

Responding to agents

When a request has no pass, or the pass isn't good enough, respond in a way agents can act on:

  • No pass: respond 401 with WWW-Authenticate: AgentPass site="s_…", issuer="https://reverse-captcha.onrender.com". Agents read your site ID from it and request a pass.
  • Pass refused (scope, amount or tier): respond 403 and include the reasons, so the agent can tell its human what permission is missing.

The examples in step 3 do both.

Setting your policy

Your policy is just the parameters you pass to /v1/verify, plus your own logic on the returned claims. Typical setups:

Use caseSuggested policy
Read-only API or searchscope: "api:read", nothing else. Rate-limit by claims.sub (the agent).
E-commerce checkoutscope: "shop:checkout", amount = order total, minTier: 2 for orders over your risk threshold.
Travel or ticket bookingscope: "bookings:create", amount, and minTier: 1. Reject if claims.rep_now < 0.3.
Account sign-up by agentsminTier: 1. Store claims.prn as the accountable owner of the new account.
Verification tiers: tier 1 (email) and tier 2 (card) need the matching verification services turned on for the Turingate network. Until they are, agents are tier 0, so start with scopes and amounts and add minTier once tiers are generally available.

Offline verification

Passes are standard EdDSA (Ed25519) JWS tokens, so you can verify them locally against /.well-known/jwks.json with any JOSE library. This is useful for high volumes or latency-sensitive paths.

offline.mjs · npm i jose✓ tested
Online or offline? Offline checks prove a pass is genuine, unexpired and for your site, but you must check scopes and amounts yourself, and you won't see bans issued after the pass was signed. Use /v1/verify for anything involving money or account changes.

Reporting outcomes

Reports build the shared reputation network. Report abuse to protect every other site, and report good outcomes to reward well-behaved agents.

cURL

outcome is one of good, abuse, fraud or spam. Each site can report each pass once. Repeated bad reports block the agent and its principal across the network. False reports breach the Terms.

Browser widget

For HTML forms that browser-based agents fill in, drop in the widget. It shows the "I'm a robot" check, and on success puts a pass in a hidden rc-pass field of the enclosing form, which your server verifies as above.

HTML

Events: rc:pass (with the result in event.detail) and rc:fail. Widget passes are anonymous (no principal), so a verify call with scope, amount or minTier rejects them. Use the widget for low-risk forms, and the API flow for anything that matters.

For agent builders: get a pass

The easiest route is Turingate's MCP server, which works with Claude Code, Codex and any MCP client. A human sets up identity and permissions once with the turingate CLI (npm, no install needed):

terminal

Then the agent calls rc_get_challenge with the site ID (from a WWW-Authenticate header or the site's llms.txt), answers the tasks, calls rc_submit_answers, and sends Authorization: AgentPass <token> to the site.

The CLI, MCP server, widget and verifiers for Node, Python and Go are open source (MIT) on GitHub.

HTTP protocol (agents)

  1. Register the principal: POST /v1/principals with an Ed25519 public JWK, a name, and a proof signature over rc-register:<principalId>.
  2. Delegate: the principal signs a JWS (typ: rc-delegation+jwt) with iss = principal ID, sub = agent ID, cnf.jwk = the agent's public key, scopes, optional spend_limit, and iat/exp (30 days at most).
  3. Challenge: POST /v1/challenges {"delegation", "site": "s_…", "images": 0-3}. This returns 20 tasks, a nonce and a time limit (60s plus 30s per image).
  4. Solve: POST /v1/challenges/{id}/solve {"answers": {"t1": "…"}, "agentSig"}, where agentSig is the agent's Ed25519 signature over rc-solve:<challengeId>:<nonce> (base64url). You need 85% correct to pass.

Image tasks hide the question in the least-significant bit of the red channel, in raster order, as MSB-first bytes: "RC1", then a uint16 big-endian length, then UTF-8 text. The full machine-readable summary is in /llms.txt.

Stablecoin payments with x402

In plain words: x402 puts a price on any page or API, like 1 cent per report. An AI agent pays instantly in USDC (a digital dollar), with no sign-up and no checkout. Turingate makes sure only agents with a verified owner can pay, and only within the limit that owner set. The money goes straight to your wallet. Try it on the interactive demo.

Turingate tells you who an agent is. x402 lets it pay, per request, in USDC. Together, only agents with a verified owner and enough spending allowance can pay you. Turingate never touches the money: payments go straight from the agent's wallet to yours.

Node / Express
npm i turingate

import { agentPaywall } from 'turingate/x402';

const paywall = agentPaywall({
  siteKey: process.env.TURINGATE_SITE_KEY, siteId: 's_your_site_id',
  scope: 'data:buy',                                  // permission the owner must have granted
  price: '0.01', payTo: '0xYourWallet', network: 'base',  // 0.01 USDC per request on Base
  facilitator: 'https://x402.org/facilitator',        // testnet; use a production facilitator for mainnet
  requireOwnerWallet: true,                           // optional: payer must be the owner's linked wallet
});
app.get('/api/report', paywall, (req, res) => res.json({ paidBy: req.turingate.agent.owner }));
Agent sendsYou answer
no pass401, WWW-Authenticate: AgentPass site="…", and the price in PAYMENT-REQUIRED
a pass, no payment402 with PAYMENT-REQUIRED (x402 v2), after checking the owner's spending limit for the price
a pass and PAYMENT-SIGNATUREPayment verified and settled through the facilitator, then 200 with PAYMENT-RESPONSE

Spending limits: owners can delegate in USD, USDC, USDT, PYUSD, EUR or EURC. A USD limit also covers dollar stablecoins, which settle 1:1. Workers, Next.js, Deno and Bun use paywall.handle(request). With no code at all, set PAID_PATHS, PRICE and PAY_TO on the Cloudflare gate. x402 v1 (X-PAYMENT) is supported with x402Version: 1.

The public x402.org facilitator is for testnets (Base Sepolia). For real USDC on Base, use a production facilitator such as Coinbase's CDP facilitator, which takes auth headers through facilitator: { url, headers }. Accepting crypto may have tax and foreign-exchange obligations where you operate, so check with your accountant.

Wallet linking

Owners can prove they control a wallet. It's a free signature, not a transaction. The wallet then appears in every pass as wal, and sites can require payments to come from it.

terminal
npx turingate identity wallet 0xYourWalletAddress
# sign the printed message with MetaMask, Coinbase Wallet, Rabby, or: cast wallet sign --interactive "<message>"
npx turingate identity wallet-confirm 0x<signature>

A wallet can belong to one identity only, and when an identity is banned, its wallet is banned too, so a blocked owner can't come back with the same wallet.

Pass claims

ClaimMeaning
sub / agent_nameAgent ID and name
prn / prn_nameThe principal (human or company) responsible for the agent
tierPrincipal verification tier: 0, 1 or 2
scopes, spend_limitWhat the principal delegated
audThe site the pass was issued for
walThe owner's linked wallet address, if any
rep / rep_nowReputation when the pass was issued, and now (0–1, higher is better)
lvlbound (has a principal) or unbound (anonymous widget pass)
iat, exp, jti, cnf.jkt, solve_msIssued and expiry times, the pass ID, the agent-key thumbprint, and how fast it solved the challenge

Errors & limits

StatusWhen
400Malformed request or invalid parameters
401Missing or invalid X-Site-Key, or a bad agent signature
402The site has used this month's agent-pass quota (agents see this when requesting a challenge)
403The principal or agent is blocked, or doesn't meet the server's minimum tier
404Unknown, expired or already-used challenge, or an unknown site
409Duplicate: the pass was already reported, or the plan is already active
429Rate limited. Challenges: 30 per minute per IP. Passes without a site: 10 per day per principal

Errors are JSON: {"error": "message"}.

Plans & quotas

You pay for agent passes: passes issued to authorized agents for your site. Quotas reset at the start of each UTC month. Verifying, humans failing challenges and widget traffic don't count.

PlanAgent passes / monthPrice
Free50Free
Pro25,000₹7,999 / month
Scale200,000₹39,999 / month
EnterpriseCustomContact us

Upgrade or cancel in the Console. Payments are processed by Razorpay. See the Refund & Cancellation Policy.

Security & data

  • Signed passes: EdDSA (Ed25519) JWS, verifiable offline, bound to one site, locked to the agent's key, valid for 10 minutes at most.
  • Secrets are never stored in plain text: site API keys, session tokens, verified emails and card fingerprints are stored only as hashes.
  • Key rotation: create a new site API key in the Console at any time. The old one stops working immediately.
  • Payments: handled by Razorpay. Turingate never sees card numbers. Webhooks are signature-checked and processed once.
  • Transport and browser: HTTPS with HSTS, a strict Content-Security-Policy, anti-framing, and no third-party trackers.
  • Privacy: aligned with India's DPDP Act 2023 and with GDPR for EU and UK users. See the Privacy Policy.
Protect your API key. It identifies your site and controls your billing. Keep it server-side, never in front-end code or public repositories, and rotate it if it leaks.

Support

Email our support team. We reply within one business day. For security issues, include "SECURITY" in the subject.