Beta WorkProof is in beta on Base Sepolia testnet. Not for production use.
Documentation Security Contract

API Reference

Base URL: https://notary-controller.fly.dev

Authentication

No API keys required. Authentication is handled via the x402 payment protocol. Each verification requires payment of 0.001 ETH on Base Sepolia.

TypeScript Interfaces

interface VerificationRequest {
  taskType: 'code-execution';
  code: string;
  expectedHash: string;
  inputData?: any;
  timeoutSeconds?: number; // 5-60, default: 30
}

interface VerificationResponse {
  jobId: string;
  status: 'pending_payment' | 'running' | 'completed' | 'error';
  result?: 'VALID' | 'INVALID' | 'ERROR';
  executionTimeMs?: number;
  registryTxHash?: string;
  expectedHash?: string;
  actualHash?: string;
  errorMessage?: string;
  refundEligible?: boolean;
}

interface PaymentRequirements {
  scheme: 'exact';
  network: 'base-sepolia';
  amount: string; // wei
  payTo: string;
  expiry: number;
}

POST /verify

Submit a verification request. Returns 402 Payment Required if no valid payment provided.

Headers

Header Required Description
Content-Type Yes Must be application/json
X-402-Payment No* Transaction hash of x402 payment (required on retry)

*First call without payment returns 402 with payment requirements.

Request Body

{
  "taskType": "code-execution",
  "code": "console.log('hello world')",
  "expectedHash": "a8f5f167f44f4964e6c998dee827110c...",
  "timeoutSeconds": 30
}

Parameters

Field Type Required Description
taskType string Yes code-execution (MVP), api-replay, data-transformation
code string Conditional Code to execute (required for code-execution)
expectedHash string Conditional Expected SHA-256 output hash
inputData any No Input data for the task
timeoutSeconds number No Max execution time (5-60s, default: 30)

Responses

402 Payment Required

{
  "jobId": "550e8400-e29b-41d4-a716-446655440000",
  "status": "pending_payment",
  "paymentRequirements": {
    "scheme": "exact",
    "network": "base-sepolia",
    "amount": "1000000000000000",
    "asset": "0x0000000000000000000000000000000000000000",
    "payTo": "0x...",
    "expiry": 1740000000
  },
  "message": "Please submit payment and retry with X-402-Payment header"
}

202 Accepted

Payment verified, verification started:

{
  "jobId": "550e8400-e29b-41d4-a716-446655440000",
  "status": "running",
  "message": "Verification started",
  "checkStatusAt": "/verify/550e8400-e29b-41d4-a716-446655440000"
}

200 OK

Verification completed (synchronous response after payment):

{
  "jobId": "550e8400-e29b-41d4-a716-446655440000",
  "status": "completed",
  "result": "VALID",
  "executionTimeMs": 245,
  "totalTimeMs": 3210,
  "registryTxHash": "0x...",
  "expectedHash": "a8f5f167f44f4964e6c998dee827110c...",
  "actualHash": "a8f5f167f44f4964e6c998dee827110c...",
  "refundEligible": false
}

GET /verify/:id

Retrieve the current status and results of a verification job.

Parameters

Parameter Type Description
id string (UUID) Job ID returned from POST /verify

Response

Pending Payment 402

{
  "jobId": "550e8400-e29b-41d4-a716-446655440000",
  "status": "pending_payment",
  "taskType": "code-execution",
  "createdAt": "2026-02-04T14:30:00.000Z",
  "updatedAt": "2026-02-04T14:30:00.000Z"
}

Running 202

{
  "jobId": "550e8400-e29b-41d4-a716-446655440000",
  "status": "running",
  "taskType": "code-execution",
  "payment": {
    "txHash": "0x...",
    "amount": "1000000000000000",
    "verifiedAt": "2026-02-04T14:30:05.000Z"
  }
}

Completed - Valid 200

{
  "jobId": "550e8400-e29b-41d4-a716-446655440000",
  "status": "completed",
  "taskType": "code-execution",
  "result": "VALID",
  "executionTimeMs": 245,
  "registryTxHash": "0x...",
  "payment": {
    "txHash": "0x...",
    "amount": "1000000000000000",
    "verifiedAt": "2026-02-04T14:30:05.000Z"
  }
}

Completed - Invalid 200

{
  "jobId": "550e8400-e29b-41d4-a716-446655440000",
  "status": "completed",
  "taskType": "code-execution",
  "result": "INVALID",
  "expectedHash": "a8f5f167f44f4964e6c998dee827110c...",
  "actualHash": "b7e4e056e33e5934d5c8877ed72f0f0f...",
  "executionTimeMs": 245,
  "registryTxHash": "0x..."
}

Webhooks (Coming Soon)

Real-time notifications for verification completion without polling.

// Register webhook URL
POST /webhooks/register
{
  "url": "https://your-api.com/webhooks/workproof",
  "events": ["verification.completed", "verification.failed"],
  "secret": "whsec_your_secret"
}

// Webhook payload
{
  "event": "verification.completed",
  "timestamp": "2026-02-04T14:30:10Z",
  "data": {
    "jobId": "550e8400-e29b-41d4-a716-446655440000",
    "result": "VALID",
    "expectedHash": "...",
    "actualHash": "..."
  },
  "signature": "sha256=..."
}

Verifying signatures:

const signature = req.headers['x-workproof-signature'];
const payload = JSON.stringify(req.body);
const expected = crypto
  .createHmac('sha256', WEBHOOK_SECRET)
  .update(payload)
  .digest('hex');

if (signature !== `sha256=${expected}`) {
  throw new Error('Invalid signature');
}

GET /notary/stats

Returns service statistics and reputation metrics.

Response

{
  "totalVerifications": 1523,
  "successRate": 94.5,
  "averageDurationMs": 320,
  "uptimePercentage": 99.9,
  "revenueETH": "1.523000",
  "activeWorkers": 3,
  "verifierAddress": "0x...",
  "serviceVersion": "0.1.0",
  "network": "base-sepolia"
}

Error Codes

Status Code Description Refund Eligible
400 Bad Request Invalid request body or parameters No
402 Payment Required No payment header provided N/A
402 Payment Failed Invalid payment (wrong amount, recipient, or already used) N/A
404 Not Found Job ID does not exist No
413 Payload Too Large Code exceeds 100KB limit No
429 Rate Limited Too many requests (100/min per IP) No
503 Service Unavailable Circuit breaker open (too many active VMs) No
500 VM Spawn Failed Infrastructure failure to start worker Yes
500 Registry Write Failed Blockchain attestation failed Yes

Rate Limits

  • 100 requests per minute per IP (unauthenticated)
  • Max 10 concurrent verifications per agent
  • Circuit breaker opens after 10 failures in 60 seconds

Refunds

Automatic refunds are issued for infrastructure failures:

Refund Eligible:

  • VM spawn failure
  • Network error during verification
  • Registry write failure
  • Timeout (>60s)

NOT Refunded:

  • INVALID result (we did the work, result is valuable info)
  • Invalid code (validation failed)
  • Wrong expected hash (user error)
Last updated: February 5, 2026