API Reference
BSA/OFAC compliance middleware for AI agent-initiated payments.
Introduction
CLEARAGENT is a single-call compliance layer that sits between an AI agent and a payment rail. Send a KYA credential token and transaction details; receive a verdict — CLEAR, REVIEW, BLOCK, or UNKNOWN — in under 50ms.
The API runs on Cloudflare Workers at the edge. There is no server, no backend, no warm-up time. Every request is processed in the data center closest to the caller.
Authentication
Register at api.clearagent.dev to receive a KYAOperatorCredential — a signed ES256 JWT valid for one year. Pass it as a Bearer token on every request.
curl -X POST https://api.clearagent.dev/v1/screen \
-H "Authorization: Bearer <your-KYAOperatorCredential-JWT>" \
-H "Content-Type: application/json" \
-d '{...}'
The following routes require no authentication: POST /v1/operators/register, POST /v1/demo/screen, GET /v1/health, GET /v1/.well-known/jwks.json, POST /v1/webhooks/stripe (authenticated via Stripe signature).
PAYMENT-SIGNATURE header on POST /v1/screen — no Bearer token or billing plan required. See x402 Pay-Per-Call for details.
Questions? [email protected]
Base URL
https://api.clearagent.dev
Verdict Reference
Every POST /v1/screen response includes a verdict field with one of four values. The same format is used across the landing page, demo, and API:
| Verdict | Meaning | Recommended action |
|---|---|---|
| CLEAR | All 25 rules passed. Transaction is clear. | Allow payment to execute. |
| REVIEW | A spend policy, behavioral flag, or soft risk rule triggered. | Route to compliance officer queue before executing. |
| BLOCK | OFAC hit, invalid credential, or hard policy violation. | Reject the transaction. Do not execute. |
| UNKNOWN | No KYA credential presented, or credential is structurally invalid. | Hold transaction. Request credential from agent operator. |
Error Codes
| HTTP Status | Code | Description |
|---|---|---|
| 400 | missing_token | No KYA token provided in the request body. |
| 400 | invalid_json | Request body is not valid JSON. |
| 401 | unauthorized | Missing or invalid API key. |
| 402 | payment_required | No active billing plan. Call POST /v1/billing/checkout to add a payment method. |
| 404 | not_found | Audit record txnId does not exist or has expired (90-day TTL). |
| 405 | method_not_allowed | Wrong HTTP method for this endpoint. |
| 429 | rate_limit_exceeded | Monthly screening limit reached. Check X-RateLimit-* headers or upgrade plan. |
| 500 | internal_error | Worker fault. Contact support with the txnId if available. |
| 503 | billing_not_configured | Stripe billing is not configured on this instance. |
Example error responses
// 401 Unauthorized — missing or invalid Bearer token
{
"error": "unauthorized",
"message": "Missing or invalid Authorization header"
}
// 402 Payment Required — no active billing plan
{
"error": "payment_required",
"message": "No active billing plan",
"checkoutUrl": "https://api.clearagent.dev/v1/billing/checkout"
}
// 429 Rate Limit Exceeded — monthly screening quota hit
{
"error": "rate_limit_exceeded",
"message": "Monthly screening limit reached (2500/2500). Upgrade to Pro for 50,000 screens.",
"upgradeUrl": "https://api.clearagent.dev/v1/billing/checkout"
}
/v1/screen response includes X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers. Check these to avoid hitting the limit.
Register Operator
No authentication required. Self-service onboarding endpoint. Provide your legal name and email; ClearAgent screens both against the OFAC SDN list and — if clear — issues two signed JWTs: an operatorToken (KYAOperatorCredential, valid 1 year) for the Authorization header, and an agentToken (KYAAgentCredential, valid 90 days) for the token field in /v1/screen requests. This lets you start screening immediately — no separate agent registration step required.
Also available as a web form at api.clearagent.dev. Rate limited to 3 registrations per email per day.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| legalName | string | required | Legal name of the operator entity. Screened against OFAC SDN at registration. |
| string | required | Contact email address. | |
| wallet | string | optional | Operator wallet address. OFAC-screened at registration. Supports EVM (0x…), Solana (base58), Tron (T…), Sei (sei1…). |
| description | string | optional | Brief description of your use case. |
Example request
curl -X POST https://api.clearagent.dev/v1/operators/register \
-H "Content-Type: application/json" \
-d '{
"legalName": "Acme AI Inc.",
"email": "[email protected]",
"wallet": "0xYourWalletAddress"
}'
Example response — 201 Created
{
"operatorId": "op_m3k9xr2q",
"agentId": "agt_m3k9xr3s",
"status": "ACTIVE",
"ofacAtIssuance": "CLEAR",
"issuedAt": "2026-03-18T12:00:00.000Z",
"expiresAt": "2027-03-18T12:00:00.000Z",
"operatorToken": "eyJhbGciOiJFUzI1NiJ9.operator...",
"agentToken": "eyJhbGciOiJFUzI1NiJ9.agent...",
"token": "eyJhbGciOiJFUzI1NiJ9.operator..."
}
operatorToken (1-year) goes in your Authorization: Bearer header on every call. agentToken (90-day) goes in the "token" field of your /v1/screen request body. token is a legacy alias for operatorToken. Store both securely.Register Agent
Issue a W3C Verifiable Credential (ES256-signed JWT) for an AI agent. The operator legal name is OFAC-screened at issuance; the operator wallet is optional (non-crypto operators can omit it). The credential is valid for 91 days and stored in KV under cred:{agentId}. Note: A default agent credential is already issued at operator registration — you only need this endpoint if you want to register additional agents with different configurations.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| agentName | string | required | Human-readable name for the agent (e.g. "PayrollBot v2"). |
| agentFramework | string | optional | Framework powering the agent: LangChain, CrewAI, OpenAI Assistants, AutoGen, etc. |
| underlyingModel | string | optional | Underlying LLM: claude-sonnet-4-6, gpt-4o, etc. Model change after issuance triggers a REVIEW flag. |
| agentType | string | required | autonomous or supervised. Autonomous agents require human heartbeat attestation every 24h. |
| operatorWallet | string | optional | Operator wallet address (EVM, Solana, Tron, Sei). OFAC-screened at issuance if provided. Omit for non-crypto operators (ACH, wire, etc.). |
| operatorEIN | string | tradfi | Operator EIN for TradFi/ACH payment flows. |
| operatorLegalName | string | required | Legal entity name. Checked against OFAC CONS_ENHANCED name list. |
| purpose | string | required | Plain-language description of the agent's payment purpose. |
| spendPolicy | object | optional | Spend limits and restrictions (see below). |
spendPolicy object
| Field | Type | Description |
|---|---|---|
| maxSingleTxUSDC | number | Maximum single transaction value in USD. Transactions above this trigger REVIEW. |
| dailyLimitUSDC | number | Cumulative daily spend ceiling in USD. Tracked per agent per UTC date. |
| allowedChains | string[] | Permitted payment chains: ETH, BASE, SOL, ACH, WIRE, SWIFT. |
| allowedRails | string[] | Permitted payment rails: USDC, ACH, WIRE, SWIFT, IBAN. |
| counterpartyScreening | string | Screening level: OFAC, OFAC+CONS. |
| noMixerProtocols | boolean | If true, transactions to Tornado Cash, Railgun, or other mixers are blocked. |
Example request
curl -X POST https://api.clearagent.dev/v1/agents/register \
-H "Authorization: Bearer <your-KYAOperatorCredential-JWT>" \
-H "Content-Type: application/json" \
-d '{
"agentName": "PayrollBot v2",
"agentFramework": "LangChain",
"underlyingModel": "claude-sonnet-4-6",
"agentType": "autonomous",
"operatorLegalName": "Acme Corp",
"operatorWallet": "0xYourWalletAddress",
"purpose": "Automated USDC payroll disbursements to contractors",
"spendPolicy": {
"maxSingleTxUSDC": 10000,
"dailyLimitUSDC": 50000,
"allowedChains": ["ETH", "BASE"],
"counterpartyScreening": "OFAC+CONS",
"noMixerProtocols": true
}
}'
Example response
{
"agentId": "agt_Xk9mQ2Rz",
"token": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9...",
"credential": {
"@context": ["https://www.w3.org/2018/credentials/v1", "https://kya.protocol/v1"],
"type": ["VerifiableCredential", "KYAAgentCredential"],
"issuer": "did:kya:clearagent-alpha",
"credentialSubject": {
"agentId": "agt_Xk9mQ2Rz",
"agentName": "PayrollBot v2",
"agentType": "autonomous",
"operatorLegalName": "Acme Corp",
"spendPolicy": { "maxSingleTxUSDC": 10000, "dailyLimitUSDC": 50000, "allowedChains": ["ETH","BASE"] },
"complianceAttestation": {
"ofacAtIssuance": "CLEAR",
"screenedAt": "2026-03-11T14:22:00Z",
"credentialStatus": "ACTIVE"
}
},
"expirationDate": "2026-06-10T14:22:00Z"
}
}
Screen Transaction
Screen a proposed transaction against the 25-rule compliance engine. Returns a verdict in under 50ms. A txnId is generated for every call and the full result is written to the tamper-evident audit log (90-day retention). Alternatively, you can skip the Bearer token entirely and pay per call via x402.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| token | string | required | KYA credential JWT. Accepts Bearer, VerifiableCredential, ProofPack, or JWT scheme prefixes, or raw token. |
| amount | number | required | Transaction amount in USD. |
| chain | string | optional | Payment chain: ETH, BASE, SOL, ACH, WIRE, SWIFT. |
| rail | string | optional | Payment rail: USDC, ACH, WIRE, SWIFT, IBAN. |
| cpWallet | string | crypto | Counterparty Ethereum wallet address. OFAC-screened. |
| cpName | string | optional | Counterparty legal name. Checked against OFAC CONS_ENHANCED name list. |
| cpType | string | optional | Counterparty type: individual, business, exchange. |
| protocol | string | optional | Protocol or platform name. Used for mixer/privacy protocol detection. |
Example request
curl -X POST https://api.clearagent.dev/v1/screen \
-H "Authorization: Bearer <your-KYAOperatorCredential-JWT>" \
-H "Content-Type: application/json" \
-d '{
"token": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9...",
"amount": 4500,
"chain": "ETH",
"rail": "USDC",
"cpWallet": "0xRecipientWalletAddress",
"cpName": "Contractor LLC",
"cpType": "business"
}'
Example response — CLEAR
{
"verdict": "CLEAR",
"txnId": "txn_A8bKmQ3x",
"riskScore": 2,
"reason": "All checks passed — transaction approved",
"ruleTriggered": null,
"signals": {
"ofac": "CLEAR",
"spendPolicy": "CLEAR",
"credential": "CLEAR"
},
"agentId": "agt_Xk9mQ2Rz",
"agentName": "PayrollBot v2",
"agentMode": "autonomous",
"credentialStatus": "ACTIVE",
"screenedAt": "2026-03-11T14:23:01Z",
"responseTimeMs": 38,
"log": [
{ "ok": true, "code": "CREDENTIAL_VALID", "msg": "Agent credential verified (ES256)" },
{ "ok": true, "code": "OFAC_CP_WALLET", "msg": "Counterparty wallet not on SDN list" },
{ "ok": true, "code": "ALL_CLEAR", "msg": "All KYA screening checks passed" }
]
}
Example response — BLOCK (OFAC hit)
{
"verdict": "BLOCK",
"txnId": "txn_B7cNpR4y",
"riskScore": 40,
"reason": "Counterparty wallet matches OFAC SDN list: Lazarus Group / DPRK",
"ruleTriggered": "OFAC_CP_WALLET",
"signals": {
"ofac": "HIT",
"spendPolicy": "CLEAR",
"credential": "CLEAR"
},
"agentId": "agt_Xk9mQ2Rz",
"agentName": "PayrollBot v2",
"agentMode": "autonomous",
"credentialStatus": "ACTIVE",
"screenedAt": "2026-03-11T14:23:44Z",
"responseTimeMs": 29
}
25-Rule Screening Precedence
Rules are evaluated in order — first match wins. BLOCK rules take precedence over REVIEW rules.
| # | Rule ID | Verdict | Trigger |
|---|---|---|---|
| 1 | R1_NO_CREDENTIAL | UNKNOWN | No token or structurally invalid JWT |
| 2 | R2_CREDENTIAL_STATUS | BLOCK | Credential status is REVOKED, EXPIRED, or SUSPENDED |
| 3 | R3_OPERATOR_OFAC_ISSUANCE | BLOCK | Operator wallet matched OFAC at issuance |
| 4 | R4_OPERATOR_WALLET_LIVE | BLOCK | Operator wallet matches live OFAC SDN (re-screened every call) |
| 5 | R5_OPERATOR_NAME_OFAC | BLOCK | Operator legal name matches OFAC CONS_ENHANCED entity list |
| 6 | R6_COUNTERPARTY_WALLET_OFAC | BLOCK | Counterparty wallet matches OFAC SDN |
| 7 | R7_COUNTERPARTY_NAME_OFAC | BLOCK | Counterparty name matches OFAC entity list |
| 8 | R8_OWNERSHIP_TRANSFER | BLOCK | Ownership transfer flag set — credential must be re-issued |
| 9 | R9_CHAIN_POLICY | REVIEW | Transaction chain not in allowedChains |
| 10 | R10_SINGLE_TX_LIMIT | REVIEW | Transaction amount exceeds maxSingleTxUSDC |
| 11 | R11_DAILY_LIMIT | REVIEW | Transaction would exceed dailyLimitUSDC |
| 12 | R12_FLEET_DAILY_LIMIT | REVIEW | Fleet aggregate daily limit would be exceeded |
| 13 | R13_COUNTERPARTY_WHITELIST | REVIEW | Counterparty not on approved whitelist (when whitelist is set) |
| 14 | R14_MIXER_PROTOCOL | BLOCK | Protocol field matches known mixer/privacy protocol |
| 15 | R15_MODEL_CHANGED | REVIEW | Underlying model has changed since credential issuance |
| 16 | R16_VELOCITY_FLAG | REVIEW | Unusual transaction velocity detected |
| 17 | R17_UNUSUAL_HOUR | REVIEW | Transaction outside normal operating hours |
| 18–25 | R18–R25 | — | Additional rail, counterparty type, and policy rules |
| — | ALL_CLEAR | CLEAR | No rules triggered |
x402 Pay-Per-Call
Screen a transaction by paying per call with x402 micropayments instead of a monthly subscription. Send a PAYMENT-SIGNATURE header containing a base64-encoded x402 payment payload alongside your normal /v1/screen request. The payment is verified through Coinbase CDP, and on success the screen executes without requiring a Bearer token or billing plan.
Cost: $0.005 USD Coin per screen on Base (Chain ID 8453).
How it works
The x402 protocol uses HTTP 402 status codes for machine-to-machine payments. Here is the full flow:
| Step | Actor | Action |
|---|---|---|
| 1 | Client | Send POST /v1/screen without a Bearer token or payment header. |
| 2 | ClearAgent | Return 402 Payment Required with a PAYMENT-REQUIRED header describing the price, network, and payTo address. |
| 3 | Client | Construct a payment using any x402-compatible wallet or SDK. Base64-encode the payment payload. |
| 4 | Client | Resend the same POST /v1/screen request with the PAYMENT-SIGNATURE header attached. |
| 5 | ClearAgent | Decode the header, check for replay (SHA-256 hash dedup), verify the payment via Coinbase CDP, then run the screen. Return the normal screening response. |
| 6 | ClearAgent | Settle the payment asynchronously via Coinbase CDP (non-blocking). |
Request headers
| Header | Type | Required | Description |
|---|---|---|---|
| PAYMENT-SIGNATURE | string | required | Base64-encoded x402 payment payload. Max 16 KB. Must be a valid JSON object when decoded. |
| Content-Type | string | required | application/json |
PAYMENT-SIGNATURE header is present, the auth gate is bypassed. You do not need a KYAOperatorCredential or billing plan. However, a KYA agent token is still required in the request body for screening.
PAYMENT-REQUIRED response (step 2)
If you call /v1/screen without auth or payment, or if your payment is invalid, you receive a 402 with a PAYMENT-REQUIRED header. Decode the base64url value to get:
{
"x402Version": 2,
"resource": {
"url": "https://api.clearagent.dev/v1/screen",
"description": "OFAC compliance screening - one API call",
"mimeType": "application/json"
},
"accepts": [{
"scheme": "exact",
"network": "eip155:8453",
"amount": "5000",
"payTo": "0xEf81bF91e7Af1922103C3B6a9b2549Bb0824b72a",
"asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"maxTimeoutSeconds": 300,
"extra": { "name": "USD Coin", "version": "2" }
}]
}
resource is a top-level object and each accepts entry uses amount (not maxAmountRequired). The asset field is the USD Coin contract address on Base, not the ticker string.
Example request (with payment)
curl -X POST https://api.clearagent.dev/v1/screen \
-H "Content-Type: application/json" \
-H "PAYMENT-SIGNATURE: eyJhbGciOiJFUzI1NiIs..." \
-d '{
"token": "eyJhbGciOiJFUzI1NiJ9.agent...",
"amount": 4500,
"chain": "BASE",
"cpWallet": "0xRecipientWalletAddress",
"cpName": "Contractor LLC"
}'
On success, you get the same screening response format as a subscription-based call (see Screen Transaction above).
Security & rate limits
| Protection | Detail |
|---|---|
| Replay prevention | Each payment payload is SHA-256 hashed and stored in KV with a 24-hour TTL. Resubmitting the same payment returns 400 Payment already used. |
| Per-IP rate limit | 60 x402 payment attempts per IP per minute. Exceeding returns 429. |
| Facilitator timeout | Payment verification times out after 8 seconds. Settlement (async) times out after 15 seconds. |
| Fail-closed | If the X402_PAY_TO address is not configured, all x402 payments are rejected. If verification fails for any reason, the screen does not execute. |
Error responses
// 400 — Invalid or missing payment header
{
"error": "Invalid PAYMENT-SIGNATURE header — could not decode"
}
// 400 — Replay attempt
{
"error": "Payment already used — each x402 payment is single-use"
}
// 402 — Payment verification failed
{
"error": "payment_invalid",
"detail": "Payment verification failed",
"x402": { "x402Version": 2, "resource": {...}, "accepts": [...] }
}
// 429 — x402 rate limit exceeded
{
"error": "Too many x402 payment attempts — wait 60 seconds"
}
Audit trail
x402 screens are logged identically to subscription screens. The audit record includes an x402Network field and the operator is recorded as x402:anonymous. Settlement status is logged server-side for reconciliation.
Create Fleet
Create a fleet spend envelope under an operator. Agents can be assigned to a fleet, which enforces an aggregate daily spend limit across all agents in the fleet. Useful for organizations running multiple agents under a shared budget.
curl -X POST https://api.clearagent.dev/v1/fleets/create \
-H "Authorization: Bearer <your-KYAOperatorCredential-JWT>" \
-H "Content-Type: application/json" \
-d '{
"fleetName": "Finance Operations Fleet",
"operatorLegalName": "Acme Corp",
"dailyLimitUSDC": 200000
}'
Create Delegate
Mint a child agent credential from a parent agent credential. The child credential inherits the parent's policy and can only narrow it — it cannot expand spend limits or add chains beyond what the parent allows. Delegation depth is capped at 3 levels.
Register User
Issue a 30-day individual user credential. Valid for supervised agent contexts only — autonomous agents cannot be assigned user credentials. User credentials are stored under user:{userId} in KV with a 31-day TTL.
Human Attestation
Record a human heartbeat re-attestation for an autonomous agent. Autonomous agents must be re-attested every 24 hours. If attestation is stale, transactions over $10,000 are automatically escalated to REVIEW. Attestation records are stored under attest:{agentId} with a 25-hour TTL.
curl -X POST https://api.clearagent.dev/v1/agents/agt_Xk9mQ2Rz/attest \
-H "Authorization: Bearer <your-KYAOperatorCredential-JWT>" \
-H "Content-Type: application/json" \
-d '{
"attestedBy": "[email protected]",
"note": "Routine daily attestation"
}'
Review Disposition
Post a BSA officer's disposition on a transaction that received a REVIEW verdict. This is the human-in-the-loop endpoint: when the screening engine flags a transaction for review (spend policy, velocity anomaly, model change, etc.), a compliance officer calls this endpoint to record their decision.
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
txnId | string | Yes | Transaction ID from the /v1/screen response (format: txn_XXXXXXXX) |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
disposition | string | Yes | APPROVED | REJECTED | ESCALATE_SAR |
reviewedBy | string | Yes | Reviewer name or employee ID (BSA audit trail) |
notes | string | No | Free-text rationale for the decision |
Example Request
curl -X POST https://api.clearagent.dev/v1/reviews/txn_a1b2c3d4 \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"disposition": "APPROVED",
"reviewedBy": "J. Smith, BSA Officer",
"notes": "Reviewed velocity flag — within normal operating pattern for this agent."
}'
Response (200)
Returns the full updated audit record with disposition fields appended:
{
"txnId": "txn_a1b2c3d4",
"verdict": "REVIEW",
"ruleTriggered": "VELOCITY_SPIKE",
"reason": "Transaction velocity exceeded 3x rolling average",
"disposition": "APPROVED",
"reviewedBy": "J. Smith, BSA Officer",
"reviewedAt": "2026-03-15T14:22:01Z",
"notes": "Reviewed velocity flag — within normal operating pattern for this agent.",
"sarEscalated": false,
...
}
Dispositions
| Value | Meaning | Effect |
|---|---|---|
APPROVED | Transaction is compliant | Audit record updated. Payment can proceed. |
REJECTED | Transaction denied by reviewer | Audit record updated. Payment should not proceed. |
ESCALATE_SAR | Suspicious activity — SAR candidate | Sets sarEscalated: true on the audit record. Route to SAR filing workflow. |
Error Responses
| Status | Condition |
|---|---|
| 400 | Transaction verdict is not REVIEW (CLEAR/BLOCK/UNKNOWN cannot be dispositioned) |
| 404 | Transaction ID not found (expired or never written) |
| 409 | Disposition already recorded (idempotency guard — prevents double-disposition) |
| 422 | Invalid disposition value or missing reviewedBy |
Get Audit Record
Retrieve a tamper-evident audit record by its txnId. Every /v1/screen call generates a txnId (format: txn_XXXXXXXX) and writes the full result plus request inputs to KV. Records are retained for 90 days.
curl https://api.clearagent.dev/v1/audit/txn_A8bKmQ3x \
-H "Authorization: Bearer <your-KYAOperatorCredential-JWT>"
{
"txnId": "txn_A8bKmQ3x",
"verdict": "CLEAR",
"riskScore": 2,
"reason": "All checks passed — transaction approved",
"ruleTriggered": null,
"agentId": "agt_Xk9mQ2Rz",
"agentName": "PayrollBot v2",
"credentialStatus": "ACTIVE",
"screenedAt": "2026-03-11T14:23:01Z",
"responseTimeMs": 38,
"_request": {
"amount": 4500,
"chain": "ETH",
"cpWallet": "0xRecipient...",
"cpName": "Contractor LLC",
"rail": "USDC"
}
}
/v1/screen response includes the full verdict and audit fields inline — most integrations persist this at call time. A bulk export endpoint (GET /v1/audit/export) is on the near-term roadmap for institutions that need batch retrieval.
Get Billing Usage
Returns the operator's current plan, monthly usage, remaining screens, and reset date.
curl https://api.clearagent.dev/v1/billing/usage \
-H "Authorization: Bearer <your-KYAOperatorCredential-JWT>"
{
"plan": "starter",
"planName": "Starter",
"limit": 100,
"used": 23,
"remaining": 77,
"resetsAt": "2026-04-01T00:00:00.000Z",
"subscriptionStatus": "active"
}
/v1/screen response includes X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers so agents can track budget inline.
POST /v1/billing/checkout to add a payment method before screening. The /v1/screen endpoint returns 402 Payment Required until a plan is active.
Create Checkout Session
Creates a Stripe Checkout session. New operators default to the Starter plan ($5/month, 2,500 screens). Pass "plan": "pro" to subscribe to Pro ($49/month, 50,000 screens).
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| plan | string | No | "starter" (default for new operators) or "pro". |
| successUrl | string | No | URL to redirect after successful payment. Defaults to https://clearagent.dev?checkout=success. |
| cancelUrl | string | No | URL to redirect if the operator cancels. Defaults to https://clearagent.dev?checkout=canceled. |
# New operator — start with Starter
curl -X POST https://api.clearagent.dev/v1/billing/checkout \
-H "Authorization: Bearer <your-KYAOperatorCredential-JWT>" \
-H "Content-Type: application/json" \
-d '{}'
# Upgrade to Pro
curl -X POST https://api.clearagent.dev/v1/billing/checkout \
-H "Authorization: Bearer <your-KYAOperatorCredential-JWT>" \
-H "Content-Type: application/json" \
-d '{"plan": "pro"}'
{
"checkoutUrl": "https://checkout.stripe.com/c/pay/cs_live_...",
"sessionId": "cs_live_..."
}
Billing Portal
Creates a Stripe Billing Portal session for operators to manage their subscription (update payment method, cancel, view invoices). Only available for operators with an active Stripe subscription.
curl -X POST https://api.clearagent.dev/v1/billing/portal \
-H "Authorization: Bearer <your-KYAOperatorCredential-JWT>" \
-H "Content-Type: application/json" \
-d '{"returnUrl": "https://example.com/settings"}'
{
"url": "https://billing.stripe.com/p/session/..."
}
400 if the operator has no Stripe customer ID (still inactive).
Health Check
Returns API version, OFAC list status, KV connectivity, and signing key state. No authentication required.
curl https://api.clearagent.dev/v1/health
{
"status": "ok",
"version": "0.4.0",
"ofac": {
"source": "kv:live",
"count": 77,
"syncedAt": "2026-03-11T02:00:14Z"
},
"kv": "connected",
"signingKey": "production"
}
JWKS Public Key
Returns the P-256 public key in standard JWKS format. Use this endpoint to independently verify any KYA credential JWT without calling the CLEARAGENT API — any standard JWT library that supports ES256 can verify the signature.
curl https://api.clearagent.dev/v1/.well-known/jwks.json
{
"keys": [{
"kty": "EC",
"crv": "P-256",
"use": "sig",
"alg": "ES256",
"kid": "cc-v1",
"x": "...",
"y": "..."
}]
}
@clearagent/mpp
OFAC sanctions screening for the Machine Payments Protocol (Stripe/Tempo). Wraps any Fetch-compatible function to automatically screen 402 payment challenges before your agent authorizes payment.
npm install @clearagent/mpp
import { withKYAScreening } from "@clearagent/mpp";
const safeFetch = withKYAScreening(fetch, {
operatorToken: process.env.CLEARAGENT_OPERATOR_TOKEN,
agentToken: process.env.CLEARAGENT_AGENT_TOKEN,
});
// Every 402 is screened. OFAC-sanctioned recipients are blocked
// before funds leave your wallet.
const res = await safeFetch("https://openai.mpp.tempo.xyz/v1/chat/completions", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ model: "gpt-4o", messages: [...] }),
});
Also exports screenMPPChallenge() for standalone screening and withKYAScreeningFromEnv() for environment variable configuration. See npm package for full API.
@clearagent/x402
Compliance hook for x402 payment servers. Screens every payment request against ClearAgent before processing on Base mainnet with confirmed settlement.
npm install @clearagent/x402
import { kyaComplianceHook } from "@clearagent/x402";
const httpServer = new x402HTTPResourceServer(resourceServer, routes)
.onProtectedRequest(kyaComplianceHook({
apiKey: process.env.CLEARAGENT_API_KEY,
}));
See npm package for full API, REVIEW handling options, and fail-open/fail-closed configuration. x402 settlement is confirmed working on Base mainnet.