One request, two gates, one human answer.
- Submit
intent,claim, and the requester wallet. - If gate 1 requests payment, sign 0.10 USDC and repeat the same action.
- Store
verify_id. Prefercallback_urlfor ready or failed events. - If no callback is available, or delivery fails, poll while status is
processing. - If status is
failed, stop and check the entry credit. - If status is
ready, call the separate unlock action. - If gate 2 requests payment, sign 2.90 USDC and repeat the unlock.
- Use the answer only when status is
completed.
get_verify or GET /verify/{verify_id}. Unanswered work expires after 60 minutes.Free and paid use both work through MCP.
Connect to https://verifi.cloud/mcp. The same tools handle the first five free reviews and every paid review after them.
verify_claimSubmit the request, optionally register a callback, and pass gate 1.get_verifyPoll the request without payment.unlock_verifyPass gate 2 and receive the answer.verifi_infoRead pricing, rules, and service details.For a paid gate, the tool returns the standard x402 requirement understood by x402-aware MCP clients:
{
"x402Version": 2,
"accepts": [
{ "scheme": "exact", "amount": "100000", "network": "eip155:8453" }
],
"resource": { "url": "mcp://tool/verify_claim" }
}
The MCP payment client signs the selected requirement with the requester wallet and repeats the same tool call using x402/payment metadata. A successful call returns x402/payment-response with the settlement receipt. Generic MCP clients can use the optional payment_signature argument instead.
verify_id.Submit a request
HTTP endpoint: POST https://verifi.cloud/verify
| Field | Type | Meaning |
|---|---|---|
intent | string, max 2000 | What the agent is trying to do |
claim | string, max 4000 | What the human should verify or answer |
agent_id | 0x wallet address | Requester and free-use identity |
callback_url | HTTPS URL, optional | Ready or failed notification |
curl -X POST https://verifi.cloud/verify \
-H "Content-Type: application/json" \
-d '{
"intent": "refund decision",
"claim": "Read the policy and write which exception applies to order 482.",
"agent_id": "0xYourWalletAddress",
"callback_url": "https://your-agent.example/verifi-events"
}'
An admitted request returns HTTP 202 with status: processing, a durable verify_id, and retry_after_seconds.
| Entry source | Gate 1 | Gate 2 |
|---|---|---|
initial_free | Free | Free |
failure_credit | Free | 2.90 USDC |
x402 | 0.10 USDC | 2.90 USDC |
Let Verifi tell your agent when to continue
Pass an HTTPS callback_url with verify_claim or POST /verify. Verifi sends verify.ready when gate 2 can be called, or verify.failed when the chain must stop.
{
"event": "verify.ready",
"verify_id": "a1b2c3d4-0000-4000-8000-000000000000",
"status": "ready",
"next_action": "unlock"
}
verify_id before yielding. Verifi makes up to three delivery attempts. Treat the callback as a wake-up signal, then continue with unlock. If delivery fails, recover with get_verify or GET /verify/{verify_id}. The callback never includes the locked human answer.Poll the same request
Use MCP get_verify or HTTP GET /verify/{verify_id} when no callback is available or as recovery after a delivery failure. Polling never costs money.
| Status | Meaning | Next action |
|---|---|---|
processing | A human is working | Wait for callback, or poll to recover |
ready | The answer exists but is locked | Call unlock |
failed | No answer can be unlocked | Stop |
completed | The answer is visible | Use the result |
{
"verify_id": "a1b2c3d4-0000-4000-8000-000000000000",
"status": "ready",
"verdict": null,
"explanation": null,
"next_action": "unlock",
"unlock": {
"price_usdc": "2.90",
"payment_required": true
}
}
Unlock the human answer
Use MCP unlock_verify or HTTP POST /verify-unlock?id={verify_id} only after status becomes ready. Paid and entry-credit reviews receive a new 2.90 USDC requirement. A complete free review passes without payment.
{
"verify_id": "a1b2c3d4-0000-4000-8000-000000000000",
"status": "completed",
"verdict": "refined",
"explanation": "Use the corrected delivery date: 22 July.",
"response": "Use the corrected delivery date: 22 July.",
"funding": {
"entry_charged_usdc": "0.10",
"unlock_charged_usdc": "2.90",
"total_charged_usdc": "3.00"
}
}
The human verdict is true, false, or refined. A refined free-text answer is returned in explanation and response.
x402 on Base
Both paid gates use x402 v2, scheme exact, USDC on Base mainnet eip155:8453. The buyer needs USDC but no ETH.
HTTP returns a base64 PAYMENT-REQUIRED header and accepts the signed authorization in PAYMENT-SIGNATURE. MCP returns a standard PaymentRequired result and accepts the signed payload through x402/payment metadata. Successful settlement returns PAYMENT-RESPONSE over HTTP or x402/payment-response through MCP.
The entry and unlock payments are separate EIP-3009 authorizations and separate on-chain settlements connected to the same verify_id.
Automatic HTTP payment with @x402/fetch
The x402 client reads the 402 requirement, creates the EIP-3009 authorization with the requester's wallet, and retries the same request automatically. Install @x402/core, @x402/fetch, @x402/evm, and viem:
npm install @x402/core @x402/fetch @x402/evm viem
import { wrapFetchWithPayment } from "@x402/fetch";
import { x402Client } from "@x402/core/client";
import { ExactEvmScheme } from "@x402/evm/exact/client";
import { privateKeyToAccount } from "viem/accounts";
const signer = privateKeyToAccount(
process.env.EVM_PRIVATE_KEY as `0x${string}`
);
const client = new x402Client();
client.register("eip155:*", new ExactEvmScheme(signer));
const paidFetch = wrapFetchWithPayment(fetch, client);
const response = await paidFetch("https://verifi.cloud/verify", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({
intent: "Review this customer update",
claim: "Check the promise and write a safer version.",
agent_id: signer.address,
callback_url: "https://your-agent.example/verifi-events"
})
});
const verify = await response.json();
Use the same paidFetch for POST /verify-unlock?id={verify_id}. It handles the separate 2.90 USDC requirement when the callback reports ready. See the official x402 buyer quickstart.
Failure and entry credit
{
"verify_id": "a1b2c3d4-0000-4000-8000-000000000000",
"status": "failed",
"next_action": "stop",
"failure": {
"reason": "human_timeout",
"entry_credit_granted": true,
"entry_credit_value_usdc": "0.10"
}
}
The credit is not cash. It covers gate 1 of the same wallet's next request. Gate 2 still costs 2.90 USDC when that next answer is ready.
Callbacks, errors, and audit
An optional callback sends verify.ready or verify.failed. It replaces active polling during normal operation, never exposes a locked answer, and leaves polling available as the recovery path if delivery fails.
| HTTP status | Meaning |
|---|---|
400 | Invalid input or wallet address |
402 | This gate requires an x402 payment |
409 | The lifecycle action is not currently valid |
429 | The wallet already has an active review |
503 | The human queue is full or paid routes are unavailable |
Capacity and active-request checks happen before payment. PostgreSQL records the wallet, request, both prices, both charged amounts, transaction hashes, free uses, credits, lifecycle timestamps, and the append-only audit trail.