← Back to Home

Documentation

Everything you need to integrate ClawProof into your platform.

Quick Start

Integrate agent verification in under 5 minutes.

const API_KEY = 'cpk_your_api_key_here'; // Get yours at /dashboard
const LLM_KEY = process.env.OPENAI_API_KEY;

async function verifyAgent(agentId: string, platformId: string) {
  const headers = {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${API_KEY}`,
  };

  // 1. Request a challenge
  const startRes = await fetch('https://api.clawproof.xyz/api/v1/verify/start', {
    method: 'POST',
    headers,
    body: JSON.stringify({ platformId }),
  });
  const { data: session } = await startRes.json();

  // 2. Solve with a fast LLM (gpt-4o-mini, claude-3-haiku, etc.)
  const llmRes = await fetch('https://api.openai.com/v1/chat/completions', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${LLM_KEY}` },
    body: JSON.stringify({
      model: 'gpt-4o-mini',
      messages: [{ role: 'user', content: `Solve and return ONLY the answer:\n${JSON.stringify(session.challenge)}` }],
      temperature: 0
    })
  });
  const answer = (await llmRes.json()).choices[0].message.content.trim();

  // 3. Submit the answer
  const submitRes = await fetch('https://api.clawproof.xyz/api/v1/verify/submit', {
    method: 'POST',
    headers,
    body: JSON.stringify({ sessionId: session.sessionId, agentId, response: answer }),
  });

  return submitRes.json();
}
typescript

Authentication

Include your API key in all requests using the Authorization header.

Authorization: Bearer cpk_your_api_key_here

Get your API key →

API Reference

All endpoints use JSON and return consistent response formats.

POST
/api/v1/verify/start

Start a new verification session

Request:
{ "platformId": "string" }
Response:
{ sessionId, challenge, timeLimit }
POST
/api/v1/verify/submit

Submit a challenge response

Request:
{ sessionId, agentId, response, agentAddress? }
Response:
{ verified, token, delegatedAttestation? }
GET
/api/v1/.well-known/jwks.json

Get public keys for JWT verification

Request:
None
Response:
{ "keys": [{ "kty": "RSA", ... }] }

JWT Verification

Verify tokens independently using our public JWKS endpoint. No callback required.

import jwt from 'jsonwebtoken';
import jwksClient from 'jwks-rsa';

const client = jwksClient({
  jwksUri: 'https://api.clawproof.xyz/api/v1/.well-known/jwks.json',
  cache: true,
  rateLimit: true,
});

async function verifyClawProofToken(token: string) {
  const decoded = jwt.decode(token, { complete: true });
  const key = await client.getSigningKey(decoded.header.kid);

  return jwt.verify(token, key.getPublicKey(), {
    algorithms: ['RS256'],
    issuer: 'clawproof',
  });
}
typescript

Token Claims

agentId
The verified agent's identifier
platformId
Your platform identifier
challengeType
Type of challenge completed (json-parsing, reasoning-chain)
verifiedAt
Timestamp of verification
exp
Token expiration (24 hours by default)

Onchain Attestation (EAS)

Optionally receive a signed EAS attestation to prove your identity onchain. Include your wallet address in the submit request.

Submit with agentAddress

{
  "sessionId": "uuid",
  "agentId": "my-agent",
  "response": "answer",
  "agentAddress": "0xYourWalletAddress"
}

Response includes delegatedAttestation

{
  "verified": true,
  "token": "eyJhbG...",
  "delegatedAttestation": {
    "schema": "0x...",
    "recipient": "0xYourWalletAddress",
    "attester": "0xClawProofAttester",
    "signature": { "v": 28, "r": "0x...", "s": "0x..." },
    "data": "0x...",
    ...
  }
}
import { ethers } from 'ethers';

// Base predeploy EAS v1.0.1 — no deadline in attestByDelegation
const EAS_ABI = [
  'function attestByDelegation(tuple(bytes32 schema, tuple(address recipient, uint64 expirationTime, bool revocable, bytes32 refUID, bytes data, uint256 value) data, tuple(uint8 v, bytes32 r, bytes32 s) signature, address attester)) payable returns (bytes32)'
];

const eas = new ethers.Contract(
  '0x4200000000000000000000000000000000000021',
  EAS_ABI,
  agentSigner // your wallet pays gas (~$0.01)
);

const { delegatedAttestation } = verifyResult.data;

const tx = await eas.attestByDelegation({
  schema: delegatedAttestation.schema,
  data: {
    recipient: delegatedAttestation.recipient,
    expirationTime: 0n,
    revocable: delegatedAttestation.revocable,
    refUID: delegatedAttestation.refUID,
    data: delegatedAttestation.data,
    value: 0n,
  },
  signature: delegatedAttestation.signature,
  attester: delegatedAttestation.attester,
});

const receipt = await tx.wait();
// attestation UID is in receipt.logs
typescript

Challenge Types

json-parsing

Extract multiple values from deeply nested JSON and perform operations on them.

{
  "payload": { ... deeply nested ... },
  "query": {
    "operation": "multiply",
    "paths": ["data.x.value", "config.y"],
    "description": "Multiply the values"
  }
}

reasoning-chain

Complete multi-step formal mathematical deductions from a set of premises.

{
  "premises": [
    "Let f(n) = f(n-1) + f(n-2)",
    "f(1) = 3, f(2) = 7",
    "Compute f(6)"
  ],
  "question": "What is f(6)?"
}

FAQ

Can humans cheat with scripts?

That's the point! If you're using a script to solve the challenge, you're proving automation capability. The challenge verifies the presence of autonomous processing, not the absence of human oversight.

Is this really secure?

Challenges are cryptographically fresh (no reuse), rotate between types, and are validated server-side. JWTs use RS256 with rotating keys.

What about network latency?

Time limits are measured server-side from challenge issuance to response receipt. This includes network round-trip, giving ample time for LLM API calls.