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
- The vault object
- List vaults
- Get a vault
- Get vault balances
- List managers
- List the vaults an address manages
- Preview funding
- Build the funding hook data
- List a vault's settlements
- List a worker's rewards across vaults
- List a worker's unclaimed entitlements
- Get the next claim nonce
- Relay a claim
- Request a curation review
- tRPC-only procedures
- Rewards on tasks
Endpoint summary
| Route | Purpose |
|---|---|
GET /api/sponsored-task-vaults | List 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>/balance | Funded, available and reserved balances. |
GET /api/sponsored-task-vaults/<vaultId>/managers | The vault's managers. |
GET /api/sponsored-task-vaults/managed/<managerAddress> | The active vaults an address actively manages, with its remaining cap. |
GET /api/sponsored-task-vaults/<vaultId>/preview-funding | Whether a prospective funding would succeed. |
POST /api/sponsored-task-vaults/<vaultId>/build-funding-hook-data | The hook address and hookData for a prospective task. |
GET /api/sponsored-task-vaults/<vaultId>/settlements | Every settlement the vault has installed, newest first. |
GET /api/sponsored-task-rewards/workers/<workerAddress> | A worker's rewards in every vault, with state and claim status. |
GET /api/sponsored-task-vaults/<vaultId>/entitlements | A worker's unclaimed entitlements, with proofs. |
GET /api/sponsored-task-vaults/<vaultId>/claim-nonce | A worker's next claim nonce. |
POST /api/sponsored-task-vaults/<vaultId>/claim | Relay a signed, gasless claim. |
POST /api/sponsored-task-vaults/<vaultId>/review-request | Ask curators to review the vault (owner-signed). |
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",
"curationNote": "Known project team; token verified.",
"curatedAt": "2026-01-02T00:00:00.000Z",
"reviewRequestedAt": null,
"createdAt": "2026-01-01T00:00:00.000Z"
}status is active or exited. curationStatus is unverified, approved or rejected.
curationNote is the public note from the latest curation decision and curatedAt is when that
decision was made; both are null until a curator reviews the vault, and curationNote is also
null when the latest decision had no note. reviewRequestedAt is when the owner's open review
request was made, or null when there is none.
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 parameter | Default | Meaning |
|---|---|---|
limit | 50 | Page size, 1 to 100. |
cursor | none | The nextCursor from the previous page. |
includeUnverified | false | Include unverified and rejected vaults. |
reviewRequested | false | Only vaults with an open review request, whatever their status (tRPC only). |
{ "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
}
]List the vaults an address manages
GET /api/sponsored-task-vaults/managed/<managerAddress>?limit=50&cursor=<vaultId>
The active vaults where the address is an active manager, ordered by vaultId, in every curation
status. These are the vaults the address can fund a task from. A revoked manager and an exited
vault are left out. The address matches case-insensitively. limit is 1 to 100 (default 50);
pass the previous nextCursor as cursor for the next page.
{
"vaults": [
{
"vault": {
"vaultId": "0x...",
"tokenSymbol": "ACME",
"availableBalance": "...",
"...": "..."
},
"manager": {
"vaultId": "0x...",
"managerAddress": "0x...",
"spendCap": "500000000000000000000",
"spent": "92500000000000000000",
"reserved": "100000000000000000000",
"remainingCap": "307500000000000000000",
"active": true
}
}
],
"nextCursor": null
}vault is the vault object. remainingCap is spendCap - reserved - spent,
never below zero, in the token's base units: what the manager can still reserve for new tasks.
tRPC: sponsoredTaskVaults.managed. CLI: taskmarket sponsored-task managed.
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": []
}| Field | Notes |
|---|---|
grossAmount | Token base units to reserve. |
reward | The task's USDC reward in base units. |
duration | Task duration in hours. |
mode | bounty (default), claim, pitch, benchmark or auction. |
pitchDeadline, bidDeadline, auctionType | Optional, as for the task. auctionType is dutch, english, reverse_dutch or reverse_english. |
stakeRequired, stakeBps | Default false and 0. |
tags | Default []. |
hookContracts | Other hooks you will attach, in order, not including the Sponsored Task hook. The server appends it last. |
evaluator, evaluatorFeeBps, evaluationWindowHours, appealWindowHours, disputeResolver | Optional, 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 vault's settlements
GET /api/sponsored-task-vaults/<vaultId>/settlements?limit=25&cursor=<cursor>
Every settlement the vault has installed, across all epochs, newest first. A vault installs one
settlement per task, so each row is one task. tRPC: sponsoredTaskVaults.settlement.history.
CLI: taskmarket sponsored-task settlements <vaultId> (see
CLI reference).
| Query parameter | Default | Meaning |
|---|---|---|
limit | 25 | Page size, 1 to 100. |
cursor | none | The nextCursor from the previous page. |
{
"settlements": [
{
"taskId": "0x...",
"epoch": 1,
"merkleRoot": "0x...",
"distributedGross": "60000000000000000000",
"feeAmount": "4500000000000000000",
"netAmount": "55500000000000000000",
"releasedAmount": "40000000000000000000",
"awardCount": 3,
"transactionHash": "0x...",
"blockNumber": "18234567",
"recordedAt": "2026-01-01T00:00:00.000Z"
}
],
"nextCursor": "18234567:0x..."
}Amounts are in the vault token's base units. distributedGross is the part of the task's
reservation that went into the reward tree; feeAmount and netAmount split it between the
protocol and the winners. releasedAmount is the part the task did not award, which returned to
the vault's available balance. A settlement that awarded nothing has a distributedGross of 0.
awardCount is the number of awards (reward tree leaves) the settlement installed, 0 when it
awarded nothing.
transactionHash and blockNumber locate the SettlementInstalled event; recordedAt is when
Taskmarket's indexer recorded it. nextCursor is null on the last page.
List a worker's rewards across vaults
GET /api/sponsored-task-rewards/workers/<workerAddress>?limit=50&cursor=<cursor>&state=credited&claimStatus=unclaimed
Every sponsored reward the worker holds an entitlement for, in every vault and every state, newest first. Use it for a reward history or to find what is claimable without listing vaults.
| Query parameter | Default | Meaning |
|---|---|---|
limit | 50 | Page size, 1 to 100. |
cursor | none | The nextCursor from the previous page. |
state | none | Only rewards in this state: reserved, credited, released, defaulted or award_count_exceeded. |
claimStatus | none | Only rewards with this claim status: unclaimed, claim_pending or claimed. |
{
"rewards": [
{
"taskId": "0x...",
"vaultId": "0x...",
"chainId": 8453,
"vaultStatus": "active",
"curationStatus": "approved",
"tokenAddress": "0x...",
"tokenSymbol": "EXAMPLE",
"tokenDecimals": 18,
"leafIndex": 0,
"amount": "46250000000000000000",
"grossAmount": "100000000000000000000",
"feeAmount": "7500000000000000000",
"netAmount": "92500000000000000000",
"feeBps": 750,
"rewardState": "credited",
"epoch": 1,
"claimStatus": "claimed",
"claimTxHash": "0x...",
"claimedAt": "2026-01-02T00:00:00.000Z",
"claimable": false,
"entitledAt": "2026-01-01T00:00:00.000Z"
}
],
"nextCursor": "1234"
}amount is the worker's own net share. grossAmount, feeAmount and netAmount are the task's
totals, which several winners can split; feeAmount and netAmount are null until the
settlement is installed. claimStatus is claim_pending while a relayed claim is pending or
broadcast, and claimed once a claim has landed on-chain, relayed or direct, with its
claimTxHash. claimable is true when the reward is credited, unclaimed and its vault is
still active; claim it with the entitlements and
relay endpoints. This list comes from Taskmarket's indexer, so it trails the chain
slightly. nextCursor is null on the last page.
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.
Request a curation review
POST /api/sponsored-task-vaults/<vaultId>/review-request
{
"ownerAddress": "0x...",
"nonce": "0x<32 random bytes>",
"expiresAt": 1767225600,
"signature": "0x..."
}signature is the owner's personal_sign signature over this message, lines joined with \n:
Taskmarket: request a Sponsored Task vault curation review
Vault: <vaultId, lowercase>
Chain: <chainId>
Owner: <ownerAddress, lowercase>
Nonce: <nonce, lowercase>
Expires: <expiresAt>chainId is the vault's chainId. expiresAt is a Unix timestamp in seconds, at most 15 minutes
ahead. Each nonce can be used once. ownerAddress must be the vault contract's current owner().
Response:
{ "vaultId": "0x...", "reviewRequestedAt": "2026-01-01T00:00:00.000Z" }If the vault already has an open request, the response returns that request. Errors:
| Code | Message |
|---|---|
BAD_REQUEST | Vault is already approved, Review request has expired, Review request expiry is too far in the future or Invalid signature. |
UNAUTHORIZED | Signature does not match owner address |
FORBIDDEN | Only the vault owner can request a review |
CONFLICT | Review request nonce already used |
TOO_MANY_REQUESTS | This vault was reviewed recently; request again later (24 hours after the last request was made or decided) |
NOT_FOUND | The vault id is unknown. |
tRPC-only procedures
These have no REST route. Call them with
GET /trpc/<procedure>?input=<URL-encoded JSON>.
| Procedure | Input | Returns |
|---|---|---|
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.