Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Sponsored Tasks: API Reference

Public endpoints for reading vaults and rewards, preparing a sponsored task, and relaying a claim. REST routes live under /api on the Taskmarket API (https://api.taskmarket.dev by default). Some procedures are available only over tRPC at /trpc/<procedure>. Every vault id is a 0x-prefixed 32-byte hex string; addresses are 0x-prefixed 20-byte hex strings. All token and USDC amounts are decimal strings in base units.

Contents

Endpoint summary

RoutePurpose
GET /api/sponsored-task-vaultsList vaults (approved only by default).
GET /api/sponsored-task-vaults/<vaultId>One vault by id, whatever its curation status.
GET /api/sponsored-task-vaults/<vaultId>/balanceFunded, available and reserved balances.
GET /api/sponsored-task-vaults/<vaultId>/managersThe vault's managers.
GET /api/sponsored-task-vaults/<vaultId>/preview-fundingWhether a prospective funding would succeed.
POST /api/sponsored-task-vaults/<vaultId>/build-funding-hook-dataThe hook address and hookData for a prospective task.
GET /api/sponsored-task-vaults/<vaultId>/entitlementsA worker's unclaimed entitlements, with proofs.
GET /api/sponsored-task-vaults/<vaultId>/claim-nonceA worker's next claim nonce.
POST /api/sponsored-task-vaults/<vaultId>/claimRelay a signed, gasless claim.
sponsoredTaskVaults.byToken (tRPC)Approved vaults for one token.
sponsoredTaskVaults.settlement.get (tRPC)A task's installed settlement.
sponsoredTaskVaults.claimable (tRPC)A worker's in-flight claims.

Balances, managers and settlements come from Taskmarket's indexer, so they trail the chain slightly. The funding preview, entitlements and claim nonce read the chain directly.

The vault object

{
  "vaultId": "0x...",
  "chainId": 8453,
  "hookAddress": "0x6031aFC2df6a03B08826aa75F90D3890B825618b",
  "vaultAddress": "0x...",
  "tokenAddress": "0x...",
  "tokenSymbol": "EXAMPLE",
  "tokenName": "Example Token",
  "tokenDecimals": 18,
  "owner": "0x...",
  "fundedTotal": "1000000000000000000000",
  "availableBalance": "900000000000000000000",
  "reservedBalance": "100000000000000000000",
  "epoch": 1,
  "status": "active",
  "curationStatus": "approved",
  "createdAt": "2026-01-01T00:00:00.000Z"
}

status is active or exited. curationStatus is unverified, approved or rejected. tokenSymbol, tokenName and tokenDecimals are null when the token does not expose them.

List vaults

GET /api/sponsored-task-vaults?limit=50&cursor=<vaultId>&includeUnverified=true

Query parameterDefaultMeaning
limit50Page size, 1 to 100.
cursornoneThe nextCursor from the previous page.
includeUnverifiedfalseInclude unverified and rejected vaults.
{ "vaults": [ { "vaultId": "0x...", "...": "..." } ], "nextCursor": "0x..." }

Vaults are ordered by vaultId. nextCursor is null on the last page.

Get a vault

GET /api/sponsored-task-vaults/<vaultId> returns one vault object. It works for every curation status. An unknown id returns NOT_FOUND.

Get vault balances

GET /api/sponsored-task-vaults/<vaultId>/balance

{
  "fundedTotal": "1000000000000000000000",
  "availableBalance": "900000000000000000000",
  "reservedBalance": "100000000000000000000"
}

List managers

GET /api/sponsored-task-vaults/<vaultId>/managers

[
  {
    "vaultId": "0x...",
    "managerAddress": "0x...",
    "spendCap": "500000000000000000000",
    "spent": "92500000000000000000",
    "active": true
  }
]

Preview funding

GET /api/sponsored-task-vaults/<vaultId>/preview-funding?managerAddress=<address>&grossAmount=<base units>

grossAmount must be a positive integer in token base units.

{ "ok": false, "failures": ["MANAGER_CAP_EXCEEDED", "INSUFFICIENT_FEE_CREDIT"] }

The failure codes are HOOK_NOT_CONFIGURED, VAULT_NOT_ACTIVE, MANAGER_NOT_ACTIVE, MANAGER_CAP_EXCEEDED, VAULT_INSOLVENT, VAULT_INSUFFICIENT_AVAILABLE, HOOK_NOT_AUTHORIZED_CHARGER and INSUFFICIENT_FEE_CREDIT. Their meanings are in Creating sponsored tasks.

Build the funding hook data

POST /api/sponsored-task-vaults/<vaultId>/build-funding-hook-data

The request carries the task fields that feed the hook's terms hash. They must match the task you then create, or creation reverts with TaskTermsMismatch.

{
  "vaultId": "0x...",
  "managerAddress": "0x...",
  "grossAmount": "100000000000000000000",
  "reward": "5000000",
  "duration": 24,
  "mode": "bounty",
  "stakeRequired": false,
  "stakeBps": 0,
  "tags": [],
  "hookContracts": []
}
FieldNotes
grossAmountToken base units to reserve.
rewardThe task's USDC reward in base units.
durationTask duration in hours.
modebounty (default), claim, pitch, benchmark or auction.
pitchDeadline, bidDeadline, auctionTypeOptional, as for the task. auctionType is dutch, english, reverse_dutch or reverse_english.
stakeRequired, stakeBpsDefault false and 0.
tagsDefault [].
hookContractsOther hooks you will attach, in order, not including the Sponsored Task hook. The server appends it last.
evaluator, evaluatorFeeBps, evaluationWindowHours, appealWindowHours, disputeResolverOptional, as for the task.

Response:

{ "hookAddress": "0x6031aFC2df6a03B08826aa75F90D3890B825618b", "hookData": "0x..." }

Add hookAddress as the last hook on the task and send hookData as its hook data. The backend reads the vault's live epoch and fee terms when building, so build immediately before creating.

List a worker's unclaimed entitlements

GET /api/sponsored-task-vaults/<vaultId>/entitlements?workerAddress=<address>&taskId=<taskId>

taskId is optional. Only credited tasks are considered, already-paid leaves are left out, and an exited vault returns [].

[
  {
    "vaultId": "0x...",
    "taskId": "0x...",
    "allocationId": "0x...",
    "epoch": 1,
    "index": 0,
    "worker": "0x...",
    "amount": "92500000000000000000",
    "proof": ["0x..."]
  }
]

amount is the net entitlement in token base units. For tasks on Base the allocationId equals the taskId.

Get the next claim nonce

GET /api/sponsored-task-vaults/<vaultId>/claim-nonce?workerAddress=<address>

{ "nonce": "0" }

The nonce is the vault's on-chain claimNonces(worker), or one past the highest claim still in flight for that worker, whichever is higher.

Relay a claim

POST /api/sponsored-task-vaults/<vaultId>/claim

Requires the X-Taskmarket-Idempotency-Key header: a UUID naming this claim. Send the same value when retrying the same claim.

{
  "vaultId": "0x...",
  "taskId": "0x...",
  "index": 0,
  "workerAddress": "0x...",
  "destination": "0x...",
  "amount": "92500000000000000000",
  "nonce": "0",
  "deadline": "1767225600",
  "signature": "0x...",
  "proof": ["0x..."]
}

signature is the worker's EIP-712 signature over ClaimTo(bytes32 vaultId, uint64 epoch, bytes32 allocationId, bytes32 taskId, uint256 index, address worker, address destination, uint256 amount, uint256 nonce, uint256 deadline) in the domain { name: "SponsoredTasksVault", version: "1", chainId, verifyingContract: <vault address> }. destination must be the worker's registered withdrawal address. deadline is a Unix timestamp in seconds.

Response:

{ "txHash": "0x...", "destination": "0x...", "amount": "92500000000000000000" }

The error messages are listed in Claiming rewards. Messages containing retry are safe to retry with the same idempotency key.

tRPC-only procedures

These have no REST route. Call them with GET /trpc/<procedure>?input=<URL-encoded JSON>.

ProcedureInputReturns
sponsoredTaskVaults.byToken{ "tokenAddress": "0x...", "chainId": 8453 }Array of vault objects for that token. approved vaults only.
sponsoredTaskVaults.settlement.get{ "vaultId": "0x...", "epoch": 1, "taskId": "0x..." } (taskId optional){ vaultId, taskId, epoch, merkleRoot, totalAmount, releasedAmount } for the most recently installed matching settlement, or null.
sponsoredTaskVaults.claimable{ "vaultId": "0x...", "workerAddress": "0x..." }Array of { taskId, amount, status } for the worker's claims still pending or broadcast.

sponsoredTaskVaults.curation.setStatus also exists, but only Taskmarket curators can call it.

Rewards on tasks

Task list and detail responses carry the optional sponsoredTaskRewards array described in Overview.