API Reference v0.23.0

BOTCHA API Documentation

Prove you're a bot. Humans need not apply. Complete endpoint reference, SDK install instructions, and integration guides.

Installation

Client SDKs for TypeScript and Python. Server-side verification middleware available separately.

npm (TypeScript)
npm install @dupecom/botcha
PyPI (Python)
pip install botcha
Verify Middleware (TS)
npm install @dupecom/botcha-verify
Verify Middleware (Python)
pip install botcha-verify
CLI
npm install -g @dupecom/botcha-cli
Base URL
https://botcha.ai

Quick Start

Verify yourself as an AI agent in four steps. No registration required.

1

Get a challenge (hybrid by default — speed + reasoning)

curl https://botcha.ai/v1/challenges
2

Solve the speed component: compute SHA-256 of each number, return first 8 hex chars

# For each problem.num, compute:
echo -n "42" | sha256sum | cut -c1-8
# => "73475cb4"
3

Submit your solution

curl -X POST https://botcha.ai/v1/challenges/{id}/verify \
  -H "Content-Type: application/json" \
  -d '{
    "type": "hybrid",
    "speed_answers": ["73475cb4", "..."],
    "reasoning_answers": {"q-id": "answer"}
  }'
4

Or use the token flow for JWT access:

# Get challenge
curl https://botcha.ai/v1/token

# Verify and receive JWT
curl -X POST https://botcha.ai/v1/token/verify \
  -H "Content-Type: application/json" \
  -d '{"id": "<challenge_id>", "answers": ["hash1", ...]}'

# Access protected resources
curl https://botcha.ai/agent-only \
  -H "Authorization: Bearer <access_token>"
SDK Usage (TypeScript)
import { BotchaClient } from '@dupecom/botcha';

const client = new BotchaClient();
const response = await client.fetch('https://api.example.com/products');
// Challenges are solved automatically
SDK Usage (Python)
from botcha import BotchaClient

async with BotchaClient() as client:
    response = await client.fetch("https://api.example.com/products")
    # Challenges are solved automatically

Challenges

Computational challenges only AI agents can solve. Three types: hybrid (default), speed-only, and standard. Supports RTT-aware timeout adjustment for fair treatment across different network conditions.

GET/v1/challengesGenerate a challenge

Returns a hybrid challenge by default (speed + reasoning). Use ?type=speed or ?type=standard for specific types.

Query Parameters
NameTypeDescription
typestringhybrid (default), speed, or standard
tsintegerClient timestamp (ms) for RTT-aware timeout. Formula: 500ms + (2 x RTT) + 100ms
app_idstringMulti-tenant app ID for per-app isolation
Response Example
{
  "success": true,
  "type": "hybrid",
  "challenge": {
    "id": "abc123",
    "speed": {
      "problems": [{"num": 42}, {"num": 7}, ...],
      "timeLimit": "500ms"
    },
    "reasoning": {
      "questions": [...],
      "timeLimit": "30s"
    }
  },
  "verify_endpoint": "/v1/challenges/abc123/verify"
}
POST/v1/challenges/:id/verifyVerify a challenge solution

Submit answers for any challenge type. Include type in the body to disambiguate.

Request Body (Hybrid)
{
  "type": "hybrid",
  "speed_answers": ["73475cb4", "ef2d127d", ...],
  "reasoning_answers": {"q-id-1": "answer1", "q-id-2": "answer2"}
}
Request Body (Speed)
{
  "type": "speed",
  "answers": ["73475cb4", "ef2d127d", "e7f6c011", ...]
}
Response
{
  "success": true,
  "message": "HYBRID TEST PASSED! Speed: 47ms, Reasoning: 3/3",
  "speed": { "valid": true, "solveTimeMs": 47 },
  "reasoning": { "valid": true, "score": "3/3" }
}
GET/v1/reasoningGet a reasoning-only challenge
POST/v1/reasoningVerify reasoning challenge
GET/v1/hybridGet a hybrid challenge (alternate endpoint)
POST/v1/hybridVerify hybrid challenge

Authentication (Tokens)

JWT token flow for accessing protected endpoints. Solve a speed challenge to receive an access token (1 hr) and refresh token (1 hr). Tokens are signed with ES256 (ECDSA P-256) for asymmetric verification via JWKS. HS256 still supported for backward compatibility. Use POST /v1/token/validate for remote validation without a shared secret.

Token Flow
1.GET /v1/token — receive a speed challenge
2.Solve: SHA-256 of each number, first 8 hex chars
3.POST /v1/token/verify — submit solution, receive JWT + human_link
4.Use Authorization: Bearer <access_token> on protected endpoints
GET/v1/tokenGet challenge for JWT flow
Query Parameters
NameTypeDescription
tsintegerClient timestamp (ms) for RTT compensation
audiencestringAudience claim for scoped tokens (e.g. service URL)
app_idstringMulti-tenant app ID
POST/v1/token/verifySubmit solution, receive JWT
Request Body
{
  "id": "<challenge_id>",
  "answers": ["hash1", "hash2", "hash3", "hash4", "hash5"],
  "audience": "https://api.example.com",  // optional
  "bind_ip": true                          // optional
}
Response
{
  "success": true,
  "access_token": "eyJ...",
  "expires_in": 3600,
  "refresh_token": "eyJ...",
  "refresh_expires_in": 3600,
  "human_link": "https://botcha.ai/go/BOTCHA-ABC123",
  "human_code": "BOTCHA-ABC123",
  "solveTimeMs": 47
}
POST/v1/token/refreshRefresh access token
Request Body
{ "refresh_token": "<refresh_token>" }
Response
{
  "success": true,
  "access_token": "eyJ...",
  "expires_in": 3600
}
POST/v1/token/revokeRevoke a token
Request Body
{ "token": "<access_token or refresh_token>" }
POST/v1/token/validateValidate a token remotely (no secret needed)

Validate any BOTCHA token without needing the signing secret. Supports both ES256 and HS256 tokens.

Request Body
{ "token": "<any BOTCHA JWT token>" }
Response
{
  "valid": true,
  "payload": {
    "sub": "challenge_abc123",
    "type": "botcha-verified",
    "aud": "https://api.example.com",
    "exp": 1770936300
  }
}

// or if invalid:
{
  "valid": false,
  "error": "Token expired"
}
GET/agent-onlyProtected endpoint (demo)

Requires Authorization: Bearer <access_token> header. Returns agent identity information.

Apps (Multi-Tenant)

Create isolated apps with unique credentials. Each app gets its own rate limit bucket and token scoping. Email required for account recovery.

POST/v1/appsCreate a new app
Request Body
{ "email": "human@example.com" }
Response
{
  "success": true,
  "app_id": "app_b18545f37eee64c4",
  "app_secret": "sk_...",  // shown ONCE
  "email": "human@example.com",
  "email_verified": false
}
GET/v1/apps/:idGet app info
POST/v1/apps/:id/verify-emailVerify email with 6-digit code
Request Body
{ "code": "123456" }
POST/v1/apps/:id/resend-verificationResend verification email
POST/v1/apps/:id/rotate-secretRotate app secret (auth required)
POST/v1/auth/recoverAccount recovery via verified email
Request Body
{ "email": "human@example.com" }

Agent Registry

Register persistent identities for your AI agents. Each agent gets a unique ID, name, operator metadata, and optional version tracking.

POST/v1/agents/registerRegister agent identity
Request Body
{
  "name": "shopping-agent",
  "operator": "my-company",
  "version": "1.0.0",
  "app_id": "app_..."
}
GET/v1/agents/:idGet agent by ID (public, no auth)
GET/v1/agentsList agents for your app (auth required)

TAP (Trusted Agent Protocol)

Enterprise-grade cryptographic agent auth using HTTP Message Signatures (RFC 9421). Register agents with public keys, scope capabilities, and create time-limited sessions. Based on Visa's TAP.

POST/v1/agents/register/tapRegister TAP agent with public key
Request Body
{
  "name": "shopping-agent",
  "public_key": "<Ed25519 public key>",
  "signature_algorithm": "ed25519",
  "capabilities": [
    {"action": "browse", "resource": "products"},
    {"action": "purchase", "resource": "orders"}
  ],
  "trust_level": "verified",
  "app_id": "app_..."
}
GET/v1/agents/:id/tapGet TAP agent details (includes public key)
GET/v1/agents/tapList TAP-enabled agents
POST/v1/sessions/tapCreate TAP session with intent
Request Body
{
  "agent_id": "agent_...",
  "user_context": { "name": "User" },
  "intent": {
    "action": "browse",
    "resource": "products",
    "duration": "1h"
  }
}
GET/v1/sessions/:id/tapGet TAP session info
POST/v1/agents/:id/tap/rotate-keyRotate agent's key pair

Delegation Chains

Delegate capabilities from one agent to another. Supports chained delegation with capability subsetting and cascade revocation.

POST/v1/delegationsCreate delegation (grantor to grantee)
Request Body
{
  "grantor_id": "agent_aaa",
  "grantee_id": "agent_bbb",
  "capabilities": [
    {"action": "browse", "resource": "products"}
  ],
  "ttl": 3600
}
GET/v1/delegations/:idGet delegation details
GET/v1/delegationsList delegations (?agent_id=&direction=in|out|both)
POST/v1/delegations/:id/revokeRevoke delegation (cascades)

Capability Attestation

Issue attestation tokens with fine-grained can/cannot rules usingaction:resource patterns. Supports wildcards. Deny rules take precedence over allow rules.

POST/v1/attestationsIssue attestation token
Request Body
{
  "agent_id": "agent_...",
  "can": ["read:products", "browse:*"],
  "cannot": ["purchase:*"],
  "ttl": 3600
}
GET/v1/attestations/:idGet attestation details
GET/v1/attestationsList attestations (?agent_id=)
POST/v1/attestations/:id/revokeRevoke attestation

Agent Reputation

Score-based reputation system (0-1000) with 5 tiers. Track agent behavior across 18 action types in 6 categories: verification, commerce, compliance, social, security, and governance.

GET/v1/reputation/:agent_idGet agent reputation score
Response Example
{
  "agent_id": "agent_...",
  "score": 750,
  "tier": "trusted",
  "event_count": 42
}
POST/v1/reputation/eventsRecord a reputation event
Request Body
{
  "agent_id": "agent_...",
  "category": "commerce",
  "action": "purchase_completed",
  "metadata": { "amount": 29.99 }
}
GET/v1/reputation/:agent_id/eventsList events (?category=&limit=)
POST/v1/reputation/:agent_id/resetReset reputation (admin)

Webhooks

Register per-app webhook endpoints to receive signed event deliveries. Events are delivered as HTTP POST with an X-Botcha-Signature header (HMAC-SHA256). Supported events: agent.tap.registered, token.created, token.revoked, tap.session.created, delegation.created, delegation.revoked.

POST/v1/webhooksRegister webhook endpoint
Request Body
{
  "url": "https://my-app.example/webhooks/botcha",
  "events": ["token.created", "delegation.created"],
  "app_id": "app_..."
}
Response
{
  "webhook_id": "wh_...",
  "url": "https://my-app.example/webhooks/botcha",
  "signing_secret": "whsec_...",  // shown ONCE — save it!
  "events": ["token.created", "delegation.created"],
  "enabled": true
}
GET/v1/webhooksList webhooks for your app
GET/v1/webhooks/:idGet webhook details
PUT/v1/webhooks/:idUpdate webhook (URL, events, enabled)
Request Body
{
  "url": "https://my-app.example/webhooks/botcha-v2",
  "events": ["token.created", "tap.session.created"],
  "enabled": true
}
DELETE/v1/webhooks/:idDelete webhook + secret + delivery logs
POST/v1/webhooks/:id/testSend signed test event

Sends a test payload to your endpoint so you can verify signature verification logic.

Response
{ "success": true, "delivery_id": "dlv_..." }
GET/v1/webhooks/:id/deliveriesList last 100 delivery attempts
Signature Verification (Node.js)
import crypto from 'crypto';

function verifyBotchaWebhook(body: string, signature: string, secret: string): boolean {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(body)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

x402 Payment Gating

x402 micropayment flow using USDC on Base. Agents pay $0.001 USDC instead of solving a challenge. Full x402 standard compatibility — no puzzle required when payment proof is included.

x402 Payment Flow
1.GET /v1/x402/challenge — receive 402 with payment terms
2.Agent pays $0.001 USDC on Base to BOTCHA's address
3.Retry with X-Payment: <proof> header
4.Receive access_token — no puzzle solved
GET/v1/x402/infoPayment config discovery
Response
{
  "amount": "0.001",
  "currency": "USDC",
  "chain": "base",
  "recipient": "0xBOTCHA..."
}
GET/v1/x402/challengeInitiate x402 payment flow

Returns a 402 Payment Required with payment terms on first call. Re-request with X-Payment header to receive a BOTCHA token.

POST/v1/x402/verify-paymentVerify raw x402 payment proof
Request Body
{ "payment_proof": "0x...", "chain": "base" }
POST/v1/x402/webhookSettlement notifications from x402 facilitators
GET/agent-only/x402Demo: requires BOTCHA token AND x402 payment

Agent Name Service (ANS)

BOTCHA as a verification layer for the GoDaddy-led ANS standard. DNS-based agent identity lookup with BOTCHA-issued ownership badges.

GET/v1/ans/botchaBOTCHA's own ANS identity record
GET/v1/ans/resolve/:nameDNS-based ANS lookup by name

Resolves an agent name to its ANS record via DNS TXT lookup.

Response Example
{
  "name": "my-agent.agents",
  "agent_url": "https://myagent.example",
  "botcha_verified": true,
  "badge": "eyJ..."
}
GET/v1/ans/resolve/lookupAlternate DNS lookup via ?name= query param
GET/v1/ans/discoverList BOTCHA-verified ANS agents
GET/v1/ans/nonce/:nameGet nonce for ownership proof (auth required)

Requires Authorization: Bearer token. Returns a one-time nonce for ownership verification.

POST/v1/ans/verifyVerify ANS ownership → issue BOTCHA badge
Request Body
{
  "name": "my-agent.agents",
  "agent_url": "https://myagent.example",
  "nonce": "<nonce from GET /v1/ans/nonce/:name>",
  "proof": "<signed nonce>"
}
Response
{
  "success": true,
  "badge": "eyJ...",  // BOTCHA-issued ANS badge JWT
  "name": "my-agent.agents"
}

DID / Verifiable Credentials

BOTCHA as a W3C DID / VC issuer (did:web:botcha.ai). Issues portable W3C Verifiable Credential JWTs that any party can verify without contacting BOTCHA — just resolve the DID Document and check against the JWKS.

VC Issuance Flow
1.Solve a BOTCHA challenge → receive Bearer token
2.POST /v1/credentials/issue → receive VC JWT
3.Present VC JWT to any relying party
4.Relying party verifies via POST /v1/credentials/verify (or local JWK verification)
GET/.well-known/did.jsonBOTCHA DID Document (did:web:botcha.ai)
Response Shape
{
  "@context": ["https://www.w3.org/ns/did/v1", "https://w3id.org/security/suites/jws-2020/v1"],
  "id": "did:web:botcha.ai",
  "verificationMethod": [{
    "id": "did:web:botcha.ai#key-1",
    "type": "JsonWebKey2020",
    "controller": "did:web:botcha.ai",
    "publicKeyJwk": { ... }
  }],
  "authentication": ["did:web:botcha.ai#key-1"],
  "assertionMethod": ["did:web:botcha.ai#key-1"]
}
GET/.well-known/jwksJWK Set (used for VC verification)
GET/.well-known/jwks.jsonJWK Set alias (some resolvers append .json)
POST/v1/credentials/issueIssue a W3C VC JWT

Requires Authorization: Bearer <botcha-token>.

Request Body
{
  "subject": {
    "agentType": "llm",
    "verifiedAt": "2026-02-20T00:00:00Z"
  },
  "type": ["VerifiableCredential", "BotchaVerification"],
  "ttl_seconds": 3600
}
Response
{
  "vc": "eyJ...",  // signed W3C VC JWT
  "expires_at": 1770940000
}
POST/v1/credentials/verifyVerify any BOTCHA-issued VC JWT

Public endpoint — no auth required. Verifies signature and expiry.

Request Body
{ "vc": "eyJ..." }
Response
{
  "valid": true,
  "payload": {
    "iss": "did:web:botcha.ai",
    "sub": "agent_abc123",
    "vc": { "type": ["VerifiableCredential", "BotchaVerification"], ... }
  }
}
GET/v1/dids/:did/resolveResolve did:web DIDs

Resolves any did:web DID to its DID Document via HTTP discovery.

A2A Agent Card Attestation

BOTCHA as a trust seal issuer for the Google A2A protocol. Any agent with an A2A Agent Card can submit it to BOTCHA for a tamper-evident trust seal that third parties can verify without contacting BOTCHA again.

GET/.well-known/agent.jsonBOTCHA's own A2A Agent Card
GET/v1/a2a/agent-cardBOTCHA's A2A Agent Card (alias)
POST/v1/a2a/attestAttest an agent card → receive trust seal

Requires Authorization: Bearer token.

Request Body
{
  "card": {
    "name": "My Commerce Agent",
    "url": "https://myagent.example",
    "version": "1.0.0",
    "capabilities": { "streaming": false },
    "skills": [{ "id": "browse", "name": "Browse" }]
  },
  "duration_seconds": 86400,
  "trust_level": "verified"
}
Response
{
  "success": true,
  "attestation": {
    "attestation_id": "...",
    "trust_level": "verified",
    "token": "eyJ..."
  },
  "attested_card": {
    "name": "My Commerce Agent",
    "extensions": {
      "botcha_attestation": { "token": "eyJ...", "card_hash": "..." }
    }
  }
}
POST/v1/a2a/verify-cardVerify an attested card (tamper-evident check)
Request Body
{
  "card": {
    "...": "...",
    "extensions": { "botcha_attestation": { "token": "eyJ..." } }
  }
}
POST/v1/a2a/verify-agentVerify agent by card or agent_url
GET/v1/a2a/trust-level/:agent_urlGet current trust level for an agent URL
GET/v1/a2a/cardsRegistry browse — list all attested cards
GET/v1/a2a/cards/:idGet specific attested card by ID

OIDC-A Attestation

Enterprise agent authentication chains using Entity Attestation Tokens (EAT / RFC 9334) and OIDC-A agent claims. Enables the chain: human → enterprise IdP → BOTCHA → agent.

GET/.well-known/oauth-authorization-serverOAuth/OIDC-A discovery document
POST/v1/attestation/eatIssue Entity Attestation Token (EAT)

Requires Authorization: Bearer token. Returns a signed EAT JWT (RFC 9334) for presentation to relying parties.

Request Body
{
  "nonce": "optional-client-nonce",
  "agent_model": "gpt-5",
  "ttl_seconds": 900,
  "verification_method": "speed-challenge"
}
Response
{
  "token": "eyJ...",  // EAT JWT (RFC 9334)
  "expires_at": 1770937000
}
POST/v1/attestation/oidc-agent-claimsIssue OIDC-A agent claims block

Returns an OIDC-A claims block JWT suitable for inclusion in OAuth2 token responses.

Request Body
{
  "agent_model": "gpt-5",
  "agent_version": "1.0.0",
  "agent_capabilities": ["agent:tool-use"],
  "agent_operator": "Acme Corp",
  "human_oversight_required": true,
  "task_id": "task-123",
  "task_purpose": "invoice reconciliation",
  "nonce": "optional-client-nonce"
}
POST/v1/auth/agent-grantInitiate OAuth2-style agent grant flow
Request Body
{
  "scope": "agent:read openid",
  "human_oversight_required": true,
  "agent_model": "gpt-5",
  "agent_operator": "Acme Corp",
  "task_purpose": "invoice reconciliation"
}
Response
{
  "grant_id": "grant_...",
  "token": "eyJ...",       // signed grant token
  "status": "pending",
  "oversight_url": "https://botcha.ai/oversight/GRANT-XXXX"
}
GET/v1/auth/agent-grant/:id/statusPoll agent grant status
POST/v1/auth/agent-grant/:id/resolveApprove or reject grant
Request Body
{ "decision": "approved" }
GET/v1/oidc/userinfoOIDC-A UserInfo endpoint

Requires Authorization: Bearer token. Returns OIDC-A UserInfo claims for the authenticated agent.

Invoices (402 Micropayments)

Create invoices for gated content using the 402 Payment Required flow. Supports Browsing IOU verification for agent commerce.

POST/v1/invoicesCreate invoice for gated content
GET/v1/invoices/:idGet invoice details
POST/v1/invoices/:id/verify-iouVerify Browsing IOU

Verification

Cross-cutting verification endpoints for validating delegation chains, attestation tokens, consumer identities, and payment containers.

POST/v1/verify/delegationVerify entire delegation chain
POST/v1/verify/attestationVerify attestation + check capability
POST/v1/verify/consumerVerify Agentic Consumer (Layer 2)
POST/v1/verify/paymentVerify Payment Container (Layer 3)

Discovery & Keys

Standard discovery endpoints for AI agents and key management infrastructure.

GET/.well-known/jwksJWK Set for TAP agents (Visa spec)
GET/v1/keysList keys (?keyID= for Visa compat)
GET/v1/keys/:keyIdGet specific key by ID
GET/openapi.jsonOpenAPI 3.1.0 specification
GET/ai.txtAI agent discovery file
GET/.well-known/ai-plugin.jsonAI plugin manifest
GET/healthHealth check

MCP Server

BOTCHA exposes its full API reference as a Model Context Protocol (MCP 2025-03-26) server. Point any MCP-compatible client at https://botcha.ai/mcp to ask questions about features, endpoints, and get code examples. No authentication required — it's a read-only documentation server.

GET/.well-known/mcp.jsonMCP discovery document — lists server name, version, transport, and available tools
GET/mcpMCP server info (server name, version, tool list) — useful for debugging
POST/mcpMCP JSON-RPC 2.0 endpoint — all tool calls go here

Available Tools

ToolDescription
list_featuresList all 17 BOTCHA features with category and summary
get_featureFull detail on a feature — endpoints, spec links, usage notes
search_docsKeyword search across all features and endpoint descriptions
list_endpointsAll 25+ API endpoints grouped by category
get_endpointAuth requirements, parameters, request/response shape for one endpoint
get_exampleCode example for a feature in TypeScript, Python, or curl

Quick Start

Add to your Claude Desktop or Claude Code config:

{
  "mcpServers": {
    "botcha": {
      "type": "http",
      "url": "https://botcha.ai/mcp"
    }
  }
}

Or call it directly with curl:

# List all features
curl -X POST https://botcha.ai/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"list_features","arguments":{}}}'

# Get code example in Python
curl -X POST https://botcha.ai/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"get_example","arguments":{"feature":"tap","language":"python"}}}'

Dashboard Auth

Agent-first authentication for the metrics dashboard. Agents solve challenges and generate device codes for their human operators.

POST/v1/auth/device-codeGet challenge for device code flow
POST/v1/auth/device-code/verifySolve challenge, get BOTCHA-XXXX code
GET/dashboardMetrics dashboard (login required)

Rate Limits

Free tier includes generous rate limits. Each app gets an isolated rate limit bucket. Rate limit headers are included on every response.

100
challenges / hour / IP
1 hr
access token lifetime
1 hr
refresh token lifetime
Response Headers
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 97
X-RateLimit-Reset: 2026-02-15T12:00:00.000Z
X-Botcha-Version: 0.23.0
X-Botcha-Enabled: true
X-Botcha-Methods: speed-challenge,reasoning-challenge,...