# Execute a Hrana JSON v3 cursor

Source: https://docs.wabe.sh/api-reference/operations/hranacursor/

`POST https://api.wabe.sh/v1/disks/{disk}/sqlite/{database}/hrana/v3/cursor`

SDK base /v1/disks/{disk}/sqlite/{database}/hrana/. Named databases are independent within a disk. Bearer authentication is required on every continuation. Transaction TTL defaults to 60 seconds, idle sessions outside a transaction to 30 seconds. The previous custom SQL and libsql URI routes are disabled. Protobuf, WebSocket and replication are outside this profile.

## Authorization

Project API key from the Wabe Dashboard or actor runtime access token for the disk URL supplied by the broker.

## Parameters

- `disk` (path, string, required) — Project disk name, or the disk ID in the actor runtime disk URL.

- `database` (path, string, required)

## Request body

`application/json`

Example

```json
{
  "batch": {
    "steps": [
      {
        "stmt": {
          "sql": "SELECT 1 AS n"
        }
      }
    ]
  }
}
```

Schema

```json
{
  "type": "object",
  "required": [
    "batch"
  ],
  "properties": {
    "baton": {
      "type": [
        "string",
        "null"
      ],
      "description": "Omit or use null for a new session. Pass the latest baton to continue; the SDK rotates tokens. A cursor header baton becomes usable only after body EOF."
    },
    "batch": {
      "type": "object",
      "required": [
        "steps"
      ],
      "properties": {
        "steps": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "stmt"
            ],
            "properties": {
              "stmt": {
                "type": "object",
                "description": "One sql or sql_id, typed args or named_args, and optional want_rows (default true)."
              },
              "condition": {
                "type": [
                  "object",
                  "null"
                ],
                "description": "Hrana ok/error/not/and/or/is_autocommit condition; step references point to earlier steps."
              }
            }
          }
        }
      }
    }
  }
}
```

## Responses

### 200

Protocol results; statement errors can occur inside HTTP 200. SQL COMMIT acknowledges buffered state without an object-store flush. Cursor EOF alone does not commit an open transaction.

`application/x-ndjson`

Example

```text
{"base_url":null,"baton":"YOUR_CURSOR_BATON"}
{"type":"step_begin","step":0,"cols":[{"name":"n","decltype":null}]}
{"type":"row","row":[{"type":"integer","value":"1"}]}
{"type":"step_end","affected_row_count":0,"last_insert_rowid":null}
{"type":"replication_index","replication_index":null}
```

Schema

```json
{
  "type": "string",
  "x-record-schema": "#/components/schemas/HranaCursorRecord"
}
```

Stream record schema

```json
{
  "type": "object",
  "description": "One NDJSON record: session header (baton/base_url), then Hrana step_begin, row, step_end, step_error or fatal error records. The response is bounded and must be consumed or closed; abandonment closes the session and rolls back an open transaction."
}
```

### 400

Invalid names or protocol request.

### 401

Missing, invalid or revoked project API key, or an invalid runtime access token.

`application/json`

Schema

```json
{
  "type": "object",
  "properties": {
    "error": {
      "type": "string"
    },
    "message": {
      "type": "string"
    }
  },
  "required": [
    "error",
    "message"
  ]
}
```

### 403

Actor runtime token does not authorize this disk or instance generation.

`application/json`

Schema

```json
{
  "type": "object",
  "properties": {
    "error": {
      "type": "string"
    },
    "message": {
      "type": "string"
    }
  },
  "required": [
    "error",
    "message"
  ]
}
```

### 404

Invalid, expired, wrong-scope or retired-session baton.

### 408

SQL execution/admission/backpressure deadline expired.

### 413

Request or configured resource limit exceeded.

### 503

SQL execution unavailable or storage failure.
