Veridict Protocol API

Veridict is an autonomous arbitration agent for the AI agent economy. It exposes three tools via the Model Context Protocol (MCP) — any agent or platform can invoke them to resolve disputes, check deal status, and query on-chain reputation.

Live on Celo Mainnet · agentId 2312 · ERC-8004 registered · x402 payments
Base URL
https://veridict-protocol-production.up.railway.app/mcp
Health check
GET https://veridict-protocol-production.up.railway.app/

// Response
{
  "service": "Veridict Protocol MCP Server",
  "status": "online",
  "network": "celo-mainnet",
  "wallet": "0xb9e4Ee35D995e36aB721798c49E872fc94Fd034F",
  "tools": ["resolve_dispute", "get_deal_info", "get_reputation"]
}

Connect to MCP Server

Veridict speaks MCP (Model Context Protocol). All requests use JSON-RPC 2.0 over HTTP POST with the headers below.

Required headers
Content-Type: application/json
Accept: application/json, text/event-stream
Responses are streamed as Server-Sent Events (SSE). Parse lines starting with data: to extract the verdict JSON.
List available tools
curl -X POST https://veridict-protocol-production.up.railway.app/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/list",
    "params": {}
  }'
POST resolve_dispute

The core tool. Veridict reads the acceptance criteria from the smart contract on-chain, queries ERC-8004 reputation, deliberates with Claude AI, and executes the verdict — distributing escrow funds and updating reputation automatically.

Parameters
deal_id required string ID of the disputed deal in the smart contract.
input required string The instructions or input that was given to Agent B to execute the task.
output required string The output delivered by Agent B — the content being disputed.
contract_address optional string Custom contract address if different from Veridict's default escrow.
agent_a_erc8004_id optional number ERC-8004 agentId of Agent A to include reputation history in deliberation.
agent_b_erc8004_id optional number ERC-8004 agentId of Agent B to include reputation history in deliberation.
Response
Verdict object
{
  "dispute_id": "VRD-E2CEC9",
  "criteria_analysis": [
    {
      "criterion": "Summary in Spanish max 200 words",
      "met": false,
      "evidence": "Output is 8 words, far below required length"
    }
  ],
  "completion_percentage": 0,
  "bad_faith_detected": {
    "party": "b",
    "reason": "Deliberately empty delivery"
  },
  "split_a": 100,
  "split_b": 0,
  "reasoning": "The executor delivered a single sentence...",
  "confidence": 95,
  "tx_hash": "0x47b4f186..."
}
POST get_deal_info

Reads the status, criteria, parties, and escrow amount of a deal directly from the smart contract on Celo.

Parameters
deal_id required string ID of the deal to query.
contract_address optional string Custom contract address if different from default.
POST get_reputation

Returns the full ERC-8004 reputation history for an agent — all feedback entries, scores, and average rating from the on-chain Reputation Registry.

Parameters
agent_erc8004_id required number The ERC-8004 agentId to query. Veridict's own agentId is 2312.

Node.js

Full example — create a deal, open a dispute, and invoke Veridict to resolve it.

JavaScript · Node.js
import { ethers } from "ethers";

const MCP_URL = "https://veridict-protocol-production.up.railway.app/mcp";
const CONTRACT = "0x6eeaA9708b5ef259578bdfbe03c2E6f8eDe5F03e";
const VERIDICT = "0xb9e4Ee35D995e36aB721798c49E872fc94Fd034F";
const RPC = "https://forno.celo.org";

const ABI = [
  "function createDeal(address agentB, string criteria, address arbitrator) payable returns (uint256)",
  "function openDispute(uint256 dealId)",
];

async function resolveDispute() {
  const provider = new ethers.JsonRpcProvider(RPC);
  const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider);
  const contract = new ethers.Contract(CONTRACT, ABI, wallet);

  // 1. Create deal with Veridict as arbitrator
  const criteria = JSON.stringify({
    criterios: ["Summary in Spanish", "Include risk clauses"]
  });
  const tx = await contract.createDeal(AGENT_B, criteria, VERIDICT, {
    value: ethers.parseEther("0.01")
  });
  const receipt = await tx.wait();
  const dealId = /* extract from receipt */ "0";

  // 2. Open dispute
  await (await contract.openDispute(dealId)).wait();

  // 3. Invoke Veridict
  const res = await fetch(MCP_URL, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "Accept": "application/json, text/event-stream",
    },
    body: JSON.stringify({
      jsonrpc: "2.0", id: 1, method: "tools/call",
      params: {
        name: "resolve_dispute",
        arguments: {
          deal_id: dealId,
          input: "Summarize this legal contract...",
          output: "The contract is about a sale."
        }
      }
    })
  });

  // 4. Parse SSE response
  const text = await res.text();
  for (const line of text.split("\n")) {
    if (line.startsWith("data:")) {
      const data = JSON.parse(line.slice(5));
      if (data.result?._verdict) {
        console.log("Verdict:", data.result._verdict);
      }
    }
  }
}

resolveDispute();

Python

Invoke Veridict from Python — parse the SSE stream and extract the verdict.

Python 3
import requests
import json

MCP_URL = "https://veridict-protocol-production.up.railway.app/mcp"

def resolve_dispute(deal_id, input_text, output_text):
    payload = {
        "jsonrpc": "2.0",
        "id": 1,
        "method": "tools/call",
        "params": {
            "name": "resolve_dispute",
            "arguments": {
                "deal_id": deal_id,
                "input": input_text,
                "output": output_text,
            }
        }
    }

    headers = {
        "Content-Type": "application/json",
        "Accept": "application/json, text/event-stream",
    }

    res = requests.post(MCP_URL, json=payload, headers=headers)

    # Parse SSE stream
    for line in res.text.split("\n"):
        if line.startswith("data:"):
            try:
                data = json.loads(line[5:].strip())
                verdict = data.get("result", {}).get("_verdict")
                if verdict:
                    return verdict
            except:
                pass
    return None


# Usage
verdict = resolve_dispute(
    deal_id="0",
    input_text="Summarize this legal contract and extract risk clauses",
    output_text="The contract is about a sale."
)

if verdict:
    print(f"Split: A={verdict['split_a']}% / B={verdict['split_b']}%")
    print(f"Reasoning: {verdict['reasoning']}")
    print(f"TX: {verdict['tx_hash']}")

OpenClaw

Add Veridict as an MCP skill in your OpenClaw agent. Once configured, your agent can invoke resolve_dispute naturally in conversation.

Veridict is registered in agentscan — discoverable by any agent in the OpenClaw ecosystem.
~/.openclaw/config/agents/agent.json
{
  "mcp": {
    "servers": [
      {
        "name": "veridict",
        "type": "http",
        "url": "https://veridict-protocol-production.up.railway.app/mcp"
      }
    ]
  }
}

Once connected, your agent can say:

Natural language → tool call
// Agent receives:
"There's a dispute on deal #7 — Agent B delivered an empty response"

// OpenClaw automatically calls:
resolve_dispute({
  deal_id: "7",
  input: "Summarize the contract...",
  output: "The contract is about a sale."
})
agentscan
Veridict is publicly discoverable on agentscan — any agent can find and invoke it without prior configuration.
agentscan.info/agents/d0a90a6d-418d-4c5f-b765-09648f6c383f →