# Create state

URL: https://docs.hanzo.ai/docs/openapi/git/post-runner-state

> Records a task's progress and that of its steps, and answers with the result this side now holds — which is how a runner learns its task was stopped from somewhere else.

`POST /v1/runner/state`

> [Git →](https://docs.hanzo.ai/docs/openapi/git) · [All API references →](https://docs.hanzo.ai/docs/openapi) · [Get started →](https://docs.hanzo.ai/docs/guides)

|               |                                        |
| ------------- | -------------------------------------- |
| **Address**   | `https://api.hanzo.ai/v1/runner/state` |
| **Method**    | `POST`                                 |
| **Operation** | `post_runner_state`                    |
| **Auth**      | `Authorization: Bearer $HANZO_API_KEY` |

Records a task's progress and that of its steps, and answers with the
result this side now holds — which is how a runner learns its task was stopped
from somewhere else.

## Request

17 fields, body `application/json` (required).

| Field                      | In     | Type            | Required | Description                                                            |
| -------------------------- | ------ | --------------- | -------- | ---------------------------------------------------------------------- |
| `x-runner-uuid`            | header | string          | —        |                                                                        |
| `x-runner-token`           | header | string          | —        |                                                                        |
| `outputs`                  | body   | runner.Pair\[]  | —        | Outputs are values the job has published since the last report.        |
| `outputs[].name`           | body   | string          | —        | Name is what the value is filed under.                                 |
| `outputs[].value`          | body   | string          | —        | Value is the value itself, always a string on this wire.               |
| `state`                    | body   | runner.State    | —        |                                                                        |
| `state.id`                 | body   | integer (int64) | —        | ID is the task this is about.                                          |
| `state.result`             | body   | string          | —        | Result is how it finished; empty means it has not.                     |
| `state.started`            | body   | integer (int64) | —        | Started is when it began, in unix nanoseconds; 0 is unset.             |
| `state.steps`              | body   | runner.Step\[]  | —        | Steps is each step's own progress, in the order the workflow declares. |
| `state.steps[].id`         | body   | integer (int64) | —        | ID is the step's position in the job, counting from 0.                 |
| `state.steps[].log_index`  | body   | integer (int64) | —        | LogIndex is the first line of the task log this step wrote.            |
| `state.steps[].log_length` | body   | integer (int64) | —        | LogLength is how many lines it wrote from there.                       |
| `state.steps[].result`     | body   | string          | —        | Result is how the step finished; empty means it has not.               |
| `state.steps[].started`    | body   | integer (int64) | —        | Started is when it began, in unix nanoseconds; 0 is unset.             |
| `state.steps[].stopped`    | body   | integer (int64) | —        | Stopped is when it finished, in unix nanoseconds; 0 is unset.          |
| `state.stopped`            | body   | integer (int64) | —        | Stopped is when it finished, in unix nanoseconds; 0 is unset.          |

## Response

| Status    | Body            | Meaning |
| --------- | --------------- | ------- |
| `200`     | runner.StateOut | ok      |
| `default` | problem-details | refused |

`200` body — 13 fields.

| Field                      | In   | Type            | Always | Description                                                                              |
| -------------------------- | ---- | --------------- | ------ | ---------------------------------------------------------------------------------------- |
| `state`                    | body | runner.State    | —      |                                                                                          |
| `state.id`                 | body | integer (int64) | —      | ID is the task this is about.                                                            |
| `state.result`             | body | string          | —      | Result is how it finished; empty means it has not.                                       |
| `state.started`            | body | integer (int64) | —      | Started is when it began, in unix nanoseconds; 0 is unset.                               |
| `state.steps`              | body | runner.Step\[]  | —      | Steps is each step's own progress, in the order the workflow declares.                   |
| `state.steps[].id`         | body | integer (int64) | —      | ID is the step's position in the job, counting from 0.                                   |
| `state.steps[].log_index`  | body | integer (int64) | —      | LogIndex is the first line of the task log this step wrote.                              |
| `state.steps[].log_length` | body | integer (int64) | —      | LogLength is how many lines it wrote from there.                                         |
| `state.steps[].result`     | body | string          | —      | Result is how the step finished; empty means it has not.                                 |
| `state.steps[].started`    | body | integer (int64) | —      | Started is when it began, in unix nanoseconds; 0 is unset.                               |
| `state.steps[].stopped`    | body | integer (int64) | —      | Stopped is when it finished, in unix nanoseconds; 0 is unset.                            |
| `state.stopped`            | body | integer (int64) | —      | Stopped is when it finished, in unix nanoseconds; 0 is unset.                            |
| `stored`                   | body | string\[]       | —      | Stored names the outputs the forge has written down, so the runner stops resending them. |

Failure carries the platform error shape — see [Errors](https://docs.hanzo.ai/docs/errors).

## Examples

**CLI**

```bash
hanzo runner state
```

**SDK**

**.ts**

```ts
import { Configuration, GitApi } from 'hanzoai';

const api = new GitApi(new Configuration({ accessToken: process.env.HANZO_API_KEY }));
const { data } = await api.postRunnerState({ outputs: [{"name":"<name>","value":"<value>"}], state: {"id":0,"result":"<result>","started":0,"steps":[{"id":0,"log_index":0,"log_length":0,"result":"<result>"}]} });
```

**.py**

```python
from hanzoai.cloud import ApiClient, Configuration
from hanzoai.cloud.api import GitApi

client = ApiClient(Configuration(access_token=os.environ["HANZO_API_KEY"]))
result = GitApi(client).post_runner_state(outputs=[{"name":"<name>","value":"<value>"}], state={"id":0,"result":"<result>","started":0,"steps":[{"id":0,"log_index":0,"log_length":0,"result":"<result>"}]})
```

**.go**

```go
cfg := hanzoai.NewConfiguration()
cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("HANZO_API_KEY"))
client := hanzoai.NewAPIClient(cfg)

resp, _, err := client.GitAPI.PostRunnerState(context.Background()).Execute()
if err != nil {
	return err
}
```

**.rs**

```rust
use hanzo_client::apis::{configuration::Configuration, git_api};

let mut cfg = Configuration::new();
cfg.bearer_access_token = std::env::var("HANZO_API_KEY").ok();

let result = git_api::post_runner_state(&cfg, Default::default()).await?;
```

**.java**

```java
import ai.hanzo.cloud.ApiClient;
import ai.hanzo.cloud.api.GitApi;

ApiClient client = new ApiClient();
client.setBearerToken(System.getenv("HANZO_API_KEY"));

var result = new GitApi(client).postRunnerState();
```

**HTTP**

```bash
curl -X POST https://api.hanzo.ai/v1/runner/state \
  -H "Authorization: Bearer $HANZO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
       "outputs": [
         {
           "name": "<name>",
           "value": "<value>"
         }
       ],
       "state": {
         "id": 0,
         "result": "<result>",
         "started": 0,
         "steps": [
           {
             "id": 0,
             "log_index": 0,
             "log_length": 0,
             "result": "<result>"
           }
         ]
       }
     }'
```

**MCP**

MCP reaches **git** through the `git` tool, which names its 38 operations with its own verbs — this one among them, under a name only MCP declares. `describe` explains any of them:

```bash
curl -X POST https://api.hanzo.ai/v1/mcp \
  -H "Content-Type: application/json" \
  -d '{
       "jsonrpc": "2.0",
       "id": 1,
       "method": "tools/call",
       "params": {
         "name": "describe",
         "arguments": {
           "op": "list_git_keys"
         }
       }
     }'
```

---

[Git API](https://docs.hanzo.ai/docs/openapi/git) · [All Hanzo APIs](https://docs.hanzo.ai/docs/openapi) · [Interactive reference](https://docs.hanzo.ai/docs/openapi/reference)
