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

# Turn (low-level)

> The low-level turn endpoint for callers that carry their own transcript state across a conversation.

Turn runs one turn of a published agent and hands the full transcript back to you. Unlike [invoke](/api/agents/invoke), which starts fresh and returns only the reply, turn is built for callers that keep conversation state themselves and replay it on each request.

```text theme={null}
POST https://api.usegradient.dev/v1/turn
```

## When to use which

| Use                          | For                                                                                                                                                                            |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| [Invoke](/api/agents/invoke) | A one-shot call. The engine drives the graph to completion for your message and returns the reply.                                                                             |
| Turn                         | A multi-turn conversation you drive. You send the running transcript and the next message; the engine returns the updated transcript for you to store and send back next time. |

The console's own conversation chat uses this route under the hood. For most integrations, invoke is enough; reach for turn when you need to inspect or persist the transcript between turns.

## Request

* **Header:** `Authorization: Bearer $GRADIENT_API_KEY`. The key needs the `agents:invoke` scope.
* **Header:** `content-type: application/json`.
* **Body:** a JSON object.

| Field            | Type    | Required | Description                                                                                                                         |
| ---------------- | ------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `agentId`        | string  | yes      | The agent UUID.                                                                                                                     |
| `nodeVersion`    | integer | yes      | A published version, `1` or greater. An API key cannot target `draft` on this route.                                                |
| `message`        | string  | yes      | The new user message for this turn.                                                                                                 |
| `messages`       | array   | no       | The transcript so far. Omit or pass `[]` on the first turn; on later turns pass the `messages` array from the previous response.    |
| `currentNodeKey` | string  | no       | The node to resume on. Omit on the first turn to start at the entrypoint; on later turns pass the value from the previous response. |
| `variables`      | object  | no       | String key/value state seeded into the conversation and substituted as `{{key}}` in prompts. Echoed back in the response.           |
| `drive`          | boolean | no       | When `true`, auto-continue the graph until it ends or waits, instead of stopping after one model turn. Defaults to `false`.         |
| `kickoff`        | boolean | no       | When `true`, allow an empty `message` to start the session at the entrypoint.                                                       |

Each entry in `messages` has this shape:

```json theme={null}
{
  "role": "assistant",
  "content": "Can I get your date of birth?",
  "nodeKey": "patient_lookup",
  "nodeVersion": 1
}
```

## Example

<CodeGroup>
  ```bash Request theme={null}
  curl -X POST https://api.usegradient.dev/v1/turn \
    -H "authorization: Bearer $GRADIENT_API_KEY" \
    -H "content-type: application/json" \
    -d '{
      "agentId": "<agent-uuid>",
      "nodeVersion": 1,
      "message": "I need to book a follow-up",
      "messages": []
    }'
  ```

  ```json Response theme={null}
  {
    "reply": "Happy to help. Can I get your date of birth?",
    "messages": [
      { "role": "user", "content": "I need to book a follow-up" },
      { "role": "assistant", "content": "Happy to help. Can I get your date of birth?", "nodeKey": "triage", "nodeVersion": 1 }
    ],
    "currentNodeKey": "triage",
    "nodeVersion": 1,
    "ended": false,
    "agentId": "<agent-uuid>",
    "traceRunId": "<trace-run-id>",
    "variables": {}
  }
  ```
</CodeGroup>

## Response

| Field            | Type    | Description                                                               |
| ---------------- | ------- | ------------------------------------------------------------------------- |
| `reply`          | string  | The agent's assistant text for this turn.                                 |
| `messages`       | array   | The full updated transcript. Send it back as `messages` on the next turn. |
| `currentNodeKey` | string  | The node the conversation is now on. Send it back as `currentNodeKey`.    |
| `nodeVersion`    | integer | The running published version.                                            |
| `ended`          | boolean | `true` once the agent has called `end_call`.                              |
| `agentId`        | string  | The agent UUID.                                                           |
| `traceRunId`     | string  | The trace run recorded for this turn.                                     |
| `variables`      | object  | The conversation's variable state after the turn.                         |

When the graph is parked on a timed wait, the response also carries `waiting: true`, a `waitUntil` timestamp, and any `waitConfig`.

## Continuing a conversation

To take the next turn, send a request with the `messages`, `currentNodeKey`, and `nodeVersion` from the previous response, plus the new `message`. Keep the same `agentId` and `nodeVersion` for the life of the conversation.

## Errors

| Status | Meaning                                                                                      |
| ------ | -------------------------------------------------------------------------------------------- |
| `400`  | `message` is missing without `kickoff`, or `agentId` or a published `nodeVersion` is missing |
| `401`  | Missing or invalid key, or the key lacks `agents:invoke`                                     |
| `402`  | Billing blocks the request                                                                   |
