World ID delegation
World ID personhood on Thirdfy delegation. Organization enrollment, single-use deposit receipts, and the CLI and MCP commands that call them.
World ID on Thirdfy is a personhood check attached to delegation. It is not a Gator signature and it is not a login. World ID issues the proof. Thirdfy stores the organization lock and, when requested, a single-use deposit receipt.
Protocol background: World ID and IDKit.
EarnOrg calls these routes for organization security. The same HTTP surface is available to CLI and MCP callers with a Thirdfy session.
Two proofs, one action
Both proofs use the action delegate-org:{orgId}.
| Proof | Signal | What complete does |
|---|---|---|
| Organization enrollment | Organization id | Locks the first verified World ID nullifier to the org. A different person fails with WORLD_ID_ORG_NULLIFIER_MISMATCH. |
| Deposit receipt | deposit:{challengeId} | Compares the nullifier to that org lock. Does not rotate the organization row. Returns a receipt id. |
begin returns an IDKit request: action, appId, environment, signal, and signed rpContext (rp_id, nonce, created_at, expires_at, signature). The client runs IDKit with that payload, with user presence required, then posts the proof object to complete.
Default chain is Base (8453).
Organization enrollment
| Step | Method | Path |
|---|---|---|
| Begin | POST | /api/v1/agent/delegation/world-id/org/begin |
| Complete | POST | /api/v1/agent/delegation/world-id/org/complete |
| Check | GET | /api/v1/agent/delegation/world-id/org/check |
Begin body: orgId, optional chainId.
Complete body: orgId, proof (the IDKit result), optional chainId.
Check query: orgId, optional chainId. The response data.worldId reports status for that organization.
Agent-scoped begin and complete also exist for a hosted agent key:
| Step | Method | Path |
|---|---|---|
| Begin | POST | /api/v1/agent/delegation/world-id/begin |
| Complete | POST | /api/v1/agent/delegation/world-id/complete |
Those bodies take agentKey instead of orgId. EarnOrg organization security uses the org routes above.
Deposit receipts
| Step | Method | Path |
|---|---|---|
| Begin | POST | /api/v1/agent/delegation/world-id/deposit/begin |
| Complete | POST | /api/v1/agent/delegation/world-id/deposit/complete |
| Consume | POST | /api/v1/agent/delegation/world-id/deposit/consume |
Begin body:
| Field | Required | Notes |
|---|---|---|
orgId | Yes | Organization the receipt belongs to |
depositSignal | No | Must be deposit:… when set. Thirdfy mints one when omitted. |
runtimeId | No | EarnOrg runtime the deposit is for |
amountUsd | No | Intended transfer amount |
destinationAddress | No | Agent wallet that should receive the funds |
chainId | No | Defaults to 8453 |
idempotencyKey | No | Caller retry key |
Complete body: orgId and proof. Success returns a receipt id. The organization enrollment row stays as it was.
Consume body: orgId and receiptId, plus optional runtimeId and amountUsd. A receipt can be consumed once. A second consume fails with WORLD_ID_DEPOSIT_RECEIPT_ALREADY_USED.
CLI
Current @thirdfy/agent-cli commands (owner session, not the agent API key alone):
Deposit begin and complete post to the deposit routes. They do not call organization enrollment complete.
MCP
| Tool | Route |
|---|---|
delegationWorldIdBegin | POST /api/v1/agent/delegation/world-id/begin |
delegationWorldIdComplete | POST /api/v1/agent/delegation/world-id/complete |
delegationWorldIdDepositBegin | POST /api/v1/agent/delegation/world-id/deposit/begin |
delegationWorldIdDepositComplete | POST /api/v1/agent/delegation/world-id/deposit/complete |