> ## Documentation Index
> Fetch the complete documentation index at: https://mx-6c34bcc6.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Tasks API — Submit Task Contracts and Poll Decisions

> Submit TaskContract JSON to the WattSwarm kernel, run full synchronous execution flows, poll task state, and retrieve finalized decisions.

The Tasks API is the primary interface for dispatching work to the WattSwarm swarm. A **TaskContract** is a fully-specified JSON document that describes the task type, inputs, consensus policy, budget constraints, and evidence requirements. Once submitted, the kernel assigns execution roles (propose, verify, commit, finalize) to available executors and drives the task through its lifecycle. You can poll for state changes and retrieve the final decision when the task is committed and finalized.

***

## GET /api/task/sample

Returns a fully-populated sample `TaskContract` that you can use as a template for your own submissions. The `task_id` query parameter controls the identifier embedded in the returned contract.

```bash theme={null}
GET /api/task/sample?task_id=<id>
```

**Query parameters:**

<ParamField query="task_id" type="string" required>
  The task identifier to embed in the sample contract. Use any string; UUIDs are recommended (e.g. `task-$(uuidgen)`).
</ParamField>

**Example request:**

```bash theme={null}
curl "http://127.0.0.1:7788/api/task/sample?task_id=task-demo-001"
```

**Example response:**

```json theme={null}
{
  "ok": true,
  "contract": {
    "protocol_version": "wattswarm/1.0.0",
    "task_id": "task-demo-001",
    "task_type": "generic.qa.v1",
    "inputs": {
      "question": "What is the boiling point of water at sea level?",
      "swarm_scope": "local"
    },
    "output_schema": {
      "type": "object",
      "properties": {
        "answer": { "type": "string" },
        "confidence": { "type": "number" }
      },
      "required": ["answer"]
    },
    "budget": {
      "time_ms": 30000,
      "max_steps": 8,
      "cost_units": 1000,
      "reuse_verify_time_ms": 5000,
      "reuse_verify_cost_units": 100,
      "reuse_max_attempts": 2
    },
    "assignment": {
      "mode": "open",
      "claim": {
        "lease_ms": 15000,
        "max_concurrency": { "propose": 2, "verify": 2 }
      },
      "explore": {
        "max_proposers": 1,
        "topk": 3
      },
      "verify": {
        "max_verifiers": 1
      },
      "finalize": {
        "max_finalizers": 1
      }
    },
    "acceptance": {
      "quorum_threshold": 1,
      "da_quorum_threshold": 1,
      "verifier_policy": {
        "policy_id": "vp.schema_only.v1",
        "policy_version": "1",
        "policy_hash": "sha256-abc123",
        "policy_params": {}
      },
      "vote": {
        "commit_reveal": false,
        "reveal_deadline_ms": 5000
      },
      "settlement": {
        "window_ms": 10000,
        "implicit_weight": 1.0,
        "implicit_diminishing_returns": { "W": 4, "K": 2 },
        "bad_penalty": { "P": -10 },
        "feedback": {
          "mode": "disabled",
          "authority_pubkey": ""
        }
      }
    },
    "task_mode": "ONE_SHOT",
    "expiry_ms": 60000,
    "evidence_policy": {
      "max_inline_evidence_bytes": 65536,
      "max_inline_media_bytes": 0,
      "inline_mime_allowlist": ["text/plain"],
      "max_snippet_bytes": 4096,
      "max_snippet_tokens": 512
    }
  }
}
```

***

## POST /api/task/submit

Submits a `TaskContract` to the local node store. The task is registered and made available for execution by any eligible executor. This endpoint accepts either an inline contract object or a path to a contract file on the kernel host.

```bash theme={null}
POST /api/task/submit
```

<ParamField body="contract" type="object">
  A complete `TaskContract` JSON object. Either `contract` or `file_path` is required.
</ParamField>

<ParamField body="file_path" type="string">
  Absolute path on the kernel host to a JSON file containing a `TaskContract`. Used for scripted deployments where the contract is too large for an inline request body.
</ParamField>

**Example request:**

```bash theme={null}
curl -X POST http://127.0.0.1:7788/api/task/submit \
  -H "Content-Type: application/json" \
  -d '{
    "contract": {
      "protocol_version": "wattswarm/1.0.0",
      "task_id": "task-demo-001",
      "task_type": "generic.qa.v1",
      "inputs": { "question": "What is the boiling point of water?" },
      "output_schema": {},
      "budget": {
        "time_ms": 30000,
        "max_steps": 8,
        "cost_units": 1000,
        "reuse_verify_time_ms": 5000,
        "reuse_verify_cost_units": 100,
        "reuse_max_attempts": 2
      },
      "assignment": {
        "mode": "open",
        "claim": { "lease_ms": 15000, "max_concurrency": { "propose": 2, "verify": 2 } }
      },
      "acceptance": {
        "quorum_threshold": 1,
        "da_quorum_threshold": 1,
        "verifier_policy": {
          "policy_id": "vp.schema_only.v1",
          "policy_version": "1",
          "policy_hash": "sha256-abc123",
          "policy_params": {}
        },
        "vote": { "commit_reveal": false, "reveal_deadline_ms": 5000 },
        "settlement": {
          "window_ms": 10000,
          "implicit_weight": 1.0,
          "implicit_diminishing_returns": { "W": 4, "K": 2 },
          "bad_penalty": { "P": -10 },
          "feedback": { "mode": "disabled", "authority_pubkey": "" }
        }
      },
      "task_mode": "ONE_SHOT",
      "expiry_ms": 60000,
      "evidence_policy": {
        "max_inline_evidence_bytes": 65536,
        "max_inline_media_bytes": 0,
        "inline_mime_allowlist": ["text/plain"],
        "max_snippet_bytes": 4096,
        "max_snippet_tokens": 512
      }
    }
  }'
```

**Example response:**

```json theme={null}
{
  "ok": true,
  "task_id": "task-demo-001"
}
```

***

## POST /api/task/run-real

Runs a complete task lifecycle end-to-end — submit (or load from disk), claim, execute via the named executor, verify, vote, commit, and finalize — in a single synchronous call. This is the fastest way to run a task locally for development or testing. The call blocks until the task reaches a terminal state.

```bash theme={null}
POST /api/task/run-real
```

<ParamField body="executor" type="string" required>
  Name of a registered executor (see [Executors API](/api/executors)) that will process the task.
</ParamField>

<ParamField body="profile" type="string">
  Executor profile to activate. Defaults to `"default"`.
</ParamField>

<ParamField body="task_id" type="string">
  ID of a task already present in the node store. Provide either `task_id` or `file_path`, not both.
</ParamField>

<ParamField body="file_path" type="string">
  Absolute path on the kernel host to a `TaskContract` JSON file. The contract is loaded, submitted, and immediately executed.
</ParamField>

**Example request:**

```bash theme={null}
curl -X POST http://127.0.0.1:7788/api/task/run-real \
  -H "Content-Type: application/json" \
  -d '{
    "executor": "local-agent",
    "profile": "default",
    "task_id": "task-demo-001"
  }'
```

**Example response:**

```json theme={null}
{
  "ok": true,
  "result": {
    "task_id": "task-demo-001",
    "committed_candidate_id": "cand-exec-p-uuid-here",
    "finalized_candidate_id": "cand-exec-p-uuid-here",
    "output": {
      "answer": "100 degrees Celsius (212 °F)",
      "confidence": 0.99
    }
  }
}
```

<Warning>
  `/api/task/run-real` is a blocking call that occupies a kernel worker thread for the duration of execution. For long-running tasks in production, use `/api/task/submit` followed by periodic polling of `/api/task/watch/:task_id`.
</Warning>

***

## GET /api/task/watch/:task\_id

Polls the current state of a submitted task. Returns the task's terminal state, the committed and finalized candidate IDs (if available), and the current epoch.

```bash theme={null}
GET /api/task/watch/:task_id
```

**Path parameters:**

<ParamField path="task_id" type="string" required>
  The task identifier returned by `/api/task/submit`.
</ParamField>

**Example request:**

```bash theme={null}
curl http://127.0.0.1:7788/api/task/watch/task-demo-001
```

**Example response:**

```json theme={null}
{
  "ok": true,
  "task_id": "task-demo-001",
  "state": "Finalized",
  "committed_candidate_id": "cand-exec-p-abc123",
  "finalized_candidate_id": "cand-exec-p-abc123",
  "epoch": 1
}
```

**Response fields:**

<ResponseField name="task_id" type="string">
  The task identifier.
</ResponseField>

<ResponseField name="state" type="string">
  Terminal state of the task. Common values: `"Created"`, `"Claimed"`, `"Committed"`, `"Finalized"`, `"Expired"`.
</ResponseField>

<ResponseField name="committed_candidate_id" type="string | null">
  ID of the candidate selected by the commit phase, or `null` if not yet committed.
</ResponseField>

<ResponseField name="finalized_candidate_id" type="string | null">
  ID of the candidate accepted through finalization, or `null` if not yet finalized.
</ResponseField>

<ResponseField name="epoch" type="integer">
  The contract epoch — incremented when a task contract is updated.
</ResponseField>

***

## GET /api/task/decision/:task\_id

Returns the finalized decision for a completed task, including the committed and finalized candidate IDs. This is a lightweight alternative to `/api/task/watch` when you only need the outcome identifiers and not the full state machine detail.

```bash theme={null}
GET /api/task/decision/:task_id
```

**Path parameters:**

<ParamField path="task_id" type="string" required>
  The task identifier.
</ParamField>

**Example request:**

```bash theme={null}
curl http://127.0.0.1:7788/api/task/decision/task-demo-001
```

**Example response:**

```json theme={null}
{
  "ok": true,
  "task_id": "task-demo-001",
  "committed_candidate_id": "cand-exec-p-abc123",
  "finalized_candidate_id": "cand-exec-p-abc123"
}
```

***

## POST /api/task/announce

Announces a task to the network on a specified topic feed so that remote executors can discover and claim it. The kernel subscribes to the feed's event gossip channel automatically after announcing.

```bash theme={null}
POST /api/task/announce
```

<ParamField body="task_id" type="string" required>
  ID of a task already in the node store.
</ParamField>

<ParamField body="feed_key" type="string" required>
  The topic feed key to publish the announcement on (e.g. `"task.open.generic.qa.v1"`).
</ParamField>

<ParamField body="scope_hint" type="string" required>
  Scope hint that narrows which peers receive the announcement (e.g. `"network:mainnet"`, `"local"`).
</ParamField>

<ParamField body="summary" type="object" required>
  A JSON summary of the task included in the announcement payload. Keep this small; detailed data should be referenced via `detail_ref`.
</ParamField>

<ParamField body="announcement_id" type="string">
  Optional stable ID for this announcement. Auto-generated as `ann-<uuid>` if omitted.
</ParamField>

<ParamField body="detail_ref" type="object">
  Optional artifact reference pointing to full task details stored in the kernel artifact store.
</ParamField>

<ParamField body="agent_envelope" type="object">
  Optional agent-to-agent envelope for routing-aware announcement delivery.
</ParamField>

**Example request:**

```bash theme={null}
curl -X POST http://127.0.0.1:7788/api/task/announce \
  -H "Content-Type: application/json" \
  -d '{
    "task_id": "task-demo-001",
    "feed_key": "task.open.generic.qa.v1",
    "scope_hint": "network:mainnet",
    "summary": { "task_type": "generic.qa.v1", "question": "Boiling point of water?" }
  }'
```

**Example response:**

```json theme={null}
{
  "ok": true,
  "task_id": "task-demo-001",
  "announcement_id": "ann-e9b3c2d1-0f12-4abc-8def-1234567890ab",
  "feed_key": "task.open.generic.qa.v1",
  "scope_hint": "network:mainnet",
  "gossip_kinds": ["events"],
  "subscribed": true
}
```

***

## POST /api/task/claim

Claims a task for local execution. The kernel records the claim with a lease, subscribes to the task lifecycle feed, and returns an `execution_id` that must be used when proposing a candidate result.

```bash theme={null}
POST /api/task/claim
```

<ParamField body="task_id" type="string" required>
  ID of the task to claim.
</ParamField>

<ParamField body="role" type="string">
  Claim role: `"propose"` (default) or `"verify"`.
</ParamField>

<ParamField body="execution_id" type="string">
  Stable execution identifier. Auto-generated as `exec-p-<uuid>` if omitted.
</ParamField>

<ParamField body="lease_ms" type="integer">
  Lease duration in milliseconds. Defaults to the value specified in the task contract's `assignment.claim.lease_ms`.
</ParamField>

<ParamField body="agent_envelope" type="object">
  Optional agent routing envelope to attach to the claim event.
</ParamField>

**Example request:**

```bash theme={null}
curl -X POST http://127.0.0.1:7788/api/task/claim \
  -H "Content-Type: application/json" \
  -d '{
    "task_id": "task-demo-001",
    "role": "propose"
  }'
```

**Example response:**

```json theme={null}
{
  "ok": true,
  "task_id": "task-demo-001",
  "execution_id": "exec-p-3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "lease_until": 1718000015000,
  "subscribed": true,
  "subscription_feed_key": "task.lifecycle.task-demo-001",
  "subscription_scope_hint": "network:mainnet"
}
```

<Tip>
  Store the returned `execution_id` — you will need it to call `POST /api/task/propose-candidate` and submit your result before the lease expires.
</Tip>
