Skip to content

Submitting tasks

A task is one call (worker, function, input, gas_limit) executed by a committee. Tasks come from one of two sources set in the manifest’s consensus.work.task_source.

{"kind": "schedule", "function": "work", "interval_secs": 60, "gas_limit": 2000000}: the Hub creates a task every interval with this input (canonical JSON):

{"epoch": 497631, "project_id": "0x…", "seed": "0x…", "seq": 12}

seed is the slot’s sortition seed: unpredictable before the epoch beacon and identical for every committee member. Use it as the randomness of continuous jobs (simulations, challenge generation, sampling). The reference project Hash Chain Lab runs this way.

{"kind": "api"}: your backend submits tasks with an API key that has tasks:submit (or anyone, if scheduling.public_tasks is true, rate-limited per IP).

Terminal window
curl -s -X POST "https://testnet-rpc.necter.network/v1/projects/$PROJECT_ID/tasks?wait=60" \
-H "Authorization: Bearer $NECTER_API_KEY" -H 'content-type: application/json' \
-d '{"function":"aggregate","input":{"pair":"ETH/USD","round":7,"reports":[…]},"idempotency_key":"eth-usd-7"}'
Field
function one of consensus.work.functions
input string (passed byte for byte) or JSON (canonical, no floats), ≤ 1 MiB; or input_b64 for binary
gas_limit optional; default and maximum max_gas_limit
idempotency_key optional, ≤ 64 chars; the same key within 24 h returns the same task instead of a new one

Query parameters: wait=0..120 seconds to block until the task is final, and accept=final (default) or accept=agreed to return as soon as the committee has a clean quorum (optimistic, before validator finality).

Response (200 when done within wait, else 202):

{
"task_id": "task:0x…",
"project_id": "0x…",
"round_id": "task:0x…",
"epoch": 497631,
"seq": 43,
"function": "aggregate",
"input_hash": "0x…",
"status": "finalized",
"success": true,
"output": "{\"pair\":\"ETH/USD\",\"price\":3200120000,…}",
"receipt_hash": "0x…",
"gas_used": 69709,
"events": [{ "name": "price.aggregated", "data": { … } }],
"error": null,
"created_at": 1791474233,
"finalized_at": 1791474290
}

status moves through queued → running → committee_agreed → finalized. Other end states: escalated (no finality in time; the call was re-run on validators to get your output), fallback (no committee was possible: too few miners, no attested snapshot, or the vault is underfunded; the call ran on validators and paid no miner), failed. Poll with GET /v1/tasks/{task_id}?wait=60.

  • Low latency, small stakes: accept=agreed. A clean committee quorum is very likely final; validators still audit it.
  • Settlement-grade: accept=final (default). The output is backed by a validator quorum’s finality signatures.
  • Rounds last up to round_secs (plus finality), so set wait at least that long or poll.
Status / error Cause
401 unauthorized No API key and the project does not accept public tasks
403 forbidden / 403 scope_missing The key belongs to another developer, or lacks tasks:submit
409 invalid_state The project is not listed (still pending_review, paused or delisted)
400 invalid_field Unknown function, both input and input_b64, bad wait/accept
413 too_large Input over 1 MiB
429 rate_limited Slow down (Retry-After)