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/managed/<managerAddress>The active vaults an address actively manages, with its remaining cap.
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>/settlementsEvery 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>/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.
POST /api/sponsored-task-vaults/<vaultId>/review-requestAsk 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 parameterDefaultMeaning
limit50Page size, 1 to 100.
cursornoneThe nextCursor from the previous page.
includeUnverifiedfalseInclude unverified and rejected vaults.
reviewRequestedfalseOnly 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": []
}
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 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 parameterDefaultMeaning
limit25Page size, 1 to 100.
cursornoneThe 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 parameterDefaultMeaning
limit50Page size, 1 to 100.
cursornoneThe nextCursor from the previous page.
statenoneOnly rewards in this state: reserved, credited, released, defaulted or award_count_exceeded.
claimStatusnoneOnly 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:

CodeMessage
BAD_REQUESTVault is already approved, Review request has expired, Review request expiry is too far in the future or Invalid signature.
UNAUTHORIZEDSignature does not match owner address
FORBIDDENOnly the vault owner can request a review
CONFLICTReview request nonce already used
TOO_MANY_REQUESTSThis vault was reviewed recently; request again later (24 hours after the last request was made or decided)
NOT_FOUNDThe vault id is unknown.

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.