> ## Documentation Index
> Fetch the complete documentation index at: https://docs.karta.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Inputs

> Resolve an approval prompt a turn paused on - approve once, approve for the session, or deny.

When the harness needs permission to act - run a tool, write a file - it emits
an [`input_required`](/concepts/streaming-events#input_required) event and the
turn pauses. You resolve it with a decision, and the turn resumes.

## The input\_required event

```text theme={null}
event: input_required
data: {"type":"input_required","session_id":"sess_9f3a...","data":{
  "request_id":"req_7c1...","kind":"tool_use","tool":"write_file",
  "message":"Allow writing orders.csv?","options":["approve_once","approve_session","deny"]
}}
```

The session also records this as `pending_input` until resolved.

| Field        | Meaning                                                        |
| ------------ | -------------------------------------------------------------- |
| `request_id` | Stable id for the pending approval. Use it in the resolve URL. |
| `kind`       | The category of request, such as `tool_use`.                   |
| `tool`       | Tool or action the harness wants to run, when available.       |
| `message`    | Human-readable approval prompt.                                |
| `options`    | Allowed decisions for this request.                            |

## Resolve it

`PUT /v1/sessions/{session_id}/inputs/{request_id}`

On the agent route family, the same operation is:
`PUT /{org}/{agent}/v1/sessions/{session_id}/inputs/{request_id}`.

<ParamField body="decision" type="string" required>
  One of `approve_once`, `approve_session`, or `deny`.
</ParamField>

```bash theme={null}
curl -X PUT https://api.karta.sh/v1/sessions/$SID/inputs/req_7c1... \
  -H "Authorization: Bearer $KARTA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"decision": "approve_once"}'
```

### Response `200`

```json theme={null}
{
  "events": [ { "type": "text", "data": { /* ... */ } }, { "type": "done", "data": { /* ... */ } } ],
  "session": { "id": "sess_9f3a...", "pending_input": null, "...": "..." }
}
```

The `events` array carries the turn's continuation after your decision; the
`session` reflects the cleared `pending_input`.

Verification signal: `session.pending_input` is `null`. If you chose `deny`, the
continuation includes a terminal `done` event whose data marks the request as
denied.

## Decisions

| Decision          | Effect                                                      |
| ----------------- | ----------------------------------------------------------- |
| `approve_once`    | Allow this one action; prompt again next time.              |
| `approve_session` | Allow this and similar actions for the rest of the session. |
| `deny`            | Refuse the action; the agent continues without it.          |

## Default behavior

How aggressively a turn prompts is governed by the session's `permission_mode`
and the [`input_required_policy`](/build/karta-toml) config - an
`autonomous` runtime maps to `approve_session`, while `interactive` prompts. In
the SDK, resolve and continue streaming with
[`session.stream_pending_input(...)`](/sdks/python/sessions#resolving-approvals).

| Symptom                | Likely cause                                               | Fix                                                                                             |
| ---------------------- | ---------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| `404`                  | The session id is not visible to the caller.               | Check the session id and API-key scope.                                                         |
| `422`                  | The request body is not valid JSON for the endpoint.       | Send `{"decision":"approve_once"}`, `{"decision":"approve_session"}`, or `{"decision":"deny"}`. |
| Turn does not continue | The `request_id` does not match the current pending input. | Re-fetch the session and resolve the active `pending_input.request_id`.                         |
