> For the complete documentation index, see [llms.txt](https://docs.currents.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.currents.dev/ai/reference/trace-api.md).

# Trace API

Every route of the Currents trace API, with its options and real output: the trace summary, the player, screen frames, filmstrips and animations, the page at any time in five formats, network requests

The trace API lets an agent read a Playwright trace one part at a time. Each trace has its own trace API link. Add a path to the link to get one part of the trace: the summary, the page at a moment, a network request, or an image. This page lists every route with its options and real output. For how an agent uses the trace API, see [Explore a trace](/ai/agentic-artifacts/explore-a-trace.md).

## Get a trace API link from a script

The REST API needs an API key with `results:read`; a Read Only key is enough. To get a link for a test from a script, use the IDs in the test's dashboard link, `/instance/<instanceId>/test/<testId>`. `ttlSeconds` sets how long the link lasts:

```bash
curl -X POST https://api.currents.dev/v1/instances/$INSTANCE_ID/trace-link \
  -H "Authorization: Bearer $CURRENTS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"testId": "'$TEST_ID'", "ttlSeconds": 604800}'
```

The response has the trace API link in `data.url` and its expiry time in `data.expiresAt`. For a trace in a session, use `POST /v1/sessions/{sessionId}/attachments/{attachmentId}/trace-link`.

For who can open a trace API link and how long it lasts, see [Share links](/ai/reference/share-links.md).

## Routes

Every route is a `GET` on the trace API link. The full specification is at [t.crts.sh/docs](https://t.crts.sh/docs), and as OpenAPI at [t.crts.sh/openapi.json](https://t.crts.sh/openapi.json).

| Route                                                                                                             | Returns                                                                                                                    |
| ----------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| [`/digest`](#summary)                                                                                             | The summary: the actions with their times, the failed action, page errors, console errors and failed requests. Start here. |
| [No path](#player)                                                                                                | A player for people: the screencast, the actions and the frames                                                            |
| [`/frames`, `/frames/failure`, `/frames/{t}`](#screen-frames)                                                     | The list of screen frames, or one frame as an image                                                                        |
| [`/filmstrip`](#filmstrip)                                                                                        | Frames from the whole recording in one image                                                                               |
| [`/animation`](#animation)                                                                                        | The recording as an animated image                                                                                         |
| [`/snapshots`, `/snapshots/failure`, `/snapshots/{id}`](#page-snapshots)                                          | The list of page snapshots, or the page at one moment in five formats                                                      |
| [`/requests`, `/requests/{index}`, `/requests/{index}/body`, `/requests/{index}/request-body`](#network-requests) | The network requests, one request, and its bodies                                                                          |
| [`/attachments`, `/attachments/{id}`](#attachments)                                                               | The files the test saved in the trace                                                                                      |
| [`/download`](#trace-zip)                                                                                         | The trace zip                                                                                                              |

Times (`t`) are milliseconds from the start of the trace; the summary gives the time of each action. A route that takes `t` returns the frame or snapshot at or before that time.

The examples on this page come from two traces. Each example says which:

* A failed test, `SAVE10 takes 10% off the total`. The test expected a total of `$206.55` and got `$183.60`.
* The checkout session from [Explore a trace](/ai/agentic-artifacts/explore-a-trace.md#example-a-checkout-that-freezes), where the **Apply** button stays on `Applying…`. Nothing in it failed, but the page threw a `TypeError`.

## Summary

| Route     | Returns                                                                                                                                                 |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `/digest` | The actions with their times, the failed action and its error, page errors, console errors, failed requests, the files in the trace, and the screencast |

| Parameter  | Values                                                                                                  |
| ---------- | ------------------------------------------------------------------------------------------------------- |
| `format`   | `json` (default) or `md`                                                                                |
| `timeline` | `auto` (default) keeps the actions near the failure and leaves out the rest. `full` lists every action. |

`/digest?format=md` is the first call. It names the failed action and its error, links to the screen and the page at the failure, and lists the actions with their times.

{% tabs %}
{% tab title="md" %}
`/digest?format=md`, the failed test, shortened:

```markdown
28 actions, 1 failed · browser: chromium · Playwright 1.63.0 · 8 network requests · 3 screencast frames

## Failing actions

### Expect "toHaveText" — `#total`

Expected: "$206.55"
Received: "$183.60"

at t=1741ms, duration 3005ms · [frame at failure](./frames/1803) · [page text at failure](./snapshots/4746?format=text) · [styled page at failure](./snapshots/4746?format=html)

## Action timeline

- · t=1649 Navigate / (32ms)
- · t=1682 Fill "save10" `internal:label="Discount code"i` (20ms)
- · t=1703 Click `internal:role=button[name="Apply"i]` (37ms)
- ✗ t=1741 Expect "toHaveText" `#total` (3005ms)
```

{% endtab %}

{% tab title="json" %}
`/digest`, the checkout session, shortened:

```json
{
  "browserName": "chromium",
  "playwrightVersion": "1.64.0-alpha-1790635538000",
  "actionCount": 9,
  "failedActionCount": 0,
  "actions": [
    { "callId": "kiwx@17", "title": "Frame.click", "startTime": 2429.996, "endTime": 2463.014, "durationMs": 33,
      "error": null, "selector": "internal:role=button[name=\"Apply\"i]" }
  ],
  "pageErrors": [
    { "name": "TypeError", "message": "Cannot destructure property 'percent' of 'DISCOUNT_CODES[code]' as it is undefined.",
      "location": "http://localhost:4183/app.js:39", "time": 2462.509 }
  ],
  "consoleErrors": [
    { "messageType": "error", "text": "Failed to load resource: the server responded with a status of 404 (Not Found)",
      "time": 665.779, "location": "http://localhost:4183/favicon.ico:0" }
  ],
  "networkFailures": [],
  "networkRequestCount": 3,
  "attachments": [],
  "screencast": { "frameCount": 12, "startTimestamp": 678.073, "endTimestamp": 3981.393 }
}
```

{% endtab %}
{% endtabs %}

## Player

| Route   | Returns                                                                         |
| ------- | ------------------------------------------------------------------------------- |
| No path | A page for people: the screencast, the actions with their times, and the frames |

The checkout session:

<figure><img src="https://3745692499-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FqmFDEiUa9mr11LUlxDnt%2Fuploads%2Fgit-blob-41d610218fd11a67791b76b1e86f94e6c7247dc2%2Ftrace-player-checkout.png?alt=media" alt="The trace API player: the screencast of the checkout with a play button and frame thumbnails, and the list of 9 actions with their times, 0 failed, 3 requests"><figcaption><p>The trace API link without a path: the checkout session in the player</p></figcaption></figure>

## Screen frames

| Route             | Returns                                                              |
| ----------------- | -------------------------------------------------------------------- |
| `/frames`         | The list of screen frames, with the time of each                     |
| `/frames/failure` | The frame when the test failed. When nothing failed, the last frame. |
| `/frames/{t}`     | The frame at or before time `t`                                      |

| Parameter     | Values                                                             |
| ------------- | ------------------------------------------------------------------ |
| `format`      | `jpeg` (default) or `webp`                                         |
| `width`       | 16 to 3840: a WebP of this width                                   |
| `placeholder` | `1`, on `/frames/failure` only. See [Placeholders](#placeholders). |

| Response header     | Value                                                                                                                   |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| `x-trace-timestamp` | The time of the frame returned                                                                                          |
| `content-location`  | The time of the frame returned, as a path next to the one asked for                                                     |
| `x-dashboard-url`   | On `/frames`: the test's page in the Currents dashboard, when the link names a test. Opening it needs a Currents login. |

`/frames`, the checkout session, shortened:

```json
{
  "playwrightVersion": "1.64.0-alpha-1790635538000",
  "traceFormatVersion": 10,
  "frameCount": 12,
  "startTimestamp": 678.073,
  "endTimestamp": 3981.393,
  "width": 1000,
  "height": 560,
  "frames": [{ "timestamp": 678.073, "width": 1000, "height": 560 }, { "timestamp": 678.638, "width": 1000, "height": 560 }]
}
```

`/frames/2464` in the checkout session returns the frame from before that time, and says which in its headers:

```http
content-type: image/jpeg
content-location: 2410.593
x-trace-timestamp: 2410.593
```

`/frames/failure`, the failed test:

<figure><img src="https://3745692499-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FqmFDEiUa9mr11LUlxDnt%2Fuploads%2Fgit-blob-e36d60b697474afcffa288449c01e52c97539160%2Ftrace-frame-failure.png?alt=media" alt="The checkout at the failure: SAVE10 applied, a discount of −$22.95 and a total of $183.60" width="584"><figcaption><p><code>/frames/failure</code>: the screen when the test failed</p></figcaption></figure>

## Filmstrip

| Route        | Returns                                           |
| ------------ | ------------------------------------------------- |
| `/filmstrip` | Frames from the whole recording in one WebP image |

| Parameter     | Values                                                                                                                                                                    |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `frames`      | 2 to 25. Default 9.                                                                                                                                                       |
| `width`       | The width of each frame, 64 to 1280. Default 320.                                                                                                                         |
| `height`      | The largest height of each frame, 16 to 1280                                                                                                                              |
| `layout`      | `grid` (default) or `row`                                                                                                                                                 |
| `end`         | `failure`: stop at the frame `/frames/failure` returns, the last one before the failure, and outline it in red. When nothing failed, the whole recording with no outline. |
| `placeholder` | `1`. See [Placeholders](#placeholders).                                                                                                                                   |

| Response header          | Value                                                  |
| ------------------------ | ------------------------------------------------------ |
| `x-filmstrip-timestamps` | The time of each frame, such as `[678,1787,2498,3981]` |

`/filmstrip?frames=4&width=640`, the checkout session:

<figure><img src="https://3745692499-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FqmFDEiUa9mr11LUlxDnt%2Fuploads%2Fgit-blob-d7b04a14498e569395b184725fabfcd2a90295e7%2Ftrace-filmstrip-checkout.png?alt=media" alt="Four frames of the checkout in a grid: the empty discount field, save10 being typed, then twice the Apply button greyed out as Applying… with the total unchanged at $229.50"><figcaption><p><code>/filmstrip?frames=4&#x26;width=640</code>: four frames of the checkout session</p></figcaption></figure>

`/filmstrip?end=failure&layout=row&width=480`, the failed test. The trace has three frames up to the failure, and the last one has a red outline:

<figure><img src="https://3745692499-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FqmFDEiUa9mr11LUlxDnt%2Fuploads%2Fgit-blob-1c054fd9bca5de62102d44868e3e3384c0e3cb6d%2Ftrace-filmstrip-failure-row.png?alt=media" alt="Three frames of the checkout in one row: save10 typed into the discount field with a total of $229.50, then the same, then outlined in red: SAVE10 applied: 10% off, a discount of −$22.95 and a total of $183.60"><figcaption><p><code>/filmstrip?end=failure&#x26;layout=row&#x26;width=480</code>: the failed test up to the failure</p></figcaption></figure>

## Animation

| Route        | Returns                            |
| ------------ | ---------------------------------- |
| `/animation` | The recording as an animated image |

| Parameter | Values                                                                                       |
| --------- | -------------------------------------------------------------------------------------------- |
| `format`  | `webp` (default) or `gif`                                                                    |
| `frames`  | 1 to 150. Default 60. A trace with fewer frames gives fewer.                                 |
| `width`   | The largest width, 16 to 2560. Default 720.                                                  |
| `quality` | The quality of a WebP, 1 to 100. Default 75.                                                 |
| `overlay` | `progress`: draw the frame number, such as `11/12`, in the bottom right corner of each frame |

| Response header             | Value                       |
| --------------------------- | --------------------------- |
| `x-animation-frames`        | The frames in the animation |
| `x-animation-source-frames` | The frames in the trace     |

`/animation?overlay=progress&width=640`, the checkout session. The trace has 12 frames, so `x-animation-frames` and `x-animation-source-frames` are both `12`:

<figure><img src="https://3745692499-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FqmFDEiUa9mr11LUlxDnt%2Fuploads%2Fgit-blob-cc1a7850bb44fe12e835824c2f924c20ad02fb55%2Ftrace-animation-progress.webp?alt=media" alt="An animation of the checkout with the frame number in the bottom right corner: save10 is typed into the discount field, Apply is clicked, and the button stays on Applying… while the total stays at $229.50" width="584"><figcaption><p><code>/animation?overlay=progress&#x26;width=640</code>: the checkout session as a WebP, with the frame number</p></figcaption></figure>

## Page snapshots

| Route                | Returns                                                                           |
| -------------------- | --------------------------------------------------------------------------------- |
| `/snapshots`         | The list of page snapshots, with the time of each                                 |
| `/snapshots/failure` | The page when the test failed. When nothing failed, the last snapshot.            |
| `/snapshots/{id}`    | One snapshot. `{id}` is a time, or a name from the list when the trace has names. |

| Parameter     | Values                                                                                                    |
| ------------- | --------------------------------------------------------------------------------------------------------- |
| `format`      | `json` (default): the snapshot's entry and the formats it has. `text`, `aria`, `dom` or `html`: the page. |
| `placeholder` | `1`, on `/snapshots/failure?format=html` only. See [Placeholders](#placeholders).                         |

| Response header     | Value                                                                                      |
| ------------------- | ------------------------------------------------------------------------------------------ |
| `x-trace-timestamp` | The time of the snapshot returned                                                          |
| `content-location`  | The snapshot returned, as a path next to the one asked for, such as `2463.971?format=text` |

`/snapshots`, the checkout session, shortened. `callId` is the action in the summary that took the snapshot:

```json
[
  { "t": 2430.515, "name": null, "phase": null, "callId": "kiwx@17", "frameUrl": "http://localhost:4183/" },
  { "t": 2463.434, "name": null, "phase": null, "callId": "kiwx@17", "frameUrl": "http://localhost:4183/" },
  { "t": 2463.971, "name": null, "phase": null, "callId": "kiwx@19", "frameUrl": "http://localhost:4183/" }
]
```

`/snapshots/2464`, the checkout session:

```json
{ "t": 2463.971, "name": null, "phase": null, "callId": "kiwx@19", "frameUrl": "http://localhost:4183/", "formats": ["json", "dom", "html", "aria", "text"] }
```

The four page formats, from the failed test:

{% tabs %}
{% tab title="text" %}
`/snapshots/failure?format=text` returns the page text, with input values and buttons:

```
Discount code
<input value="save10" placeholder="e.g. SAVE10">
<button>
Apply
SAVE10 applied: 10% off
Subtotal
$229.50
Discount
−$22.95
Total
$183.60
```

{% endtab %}

{% tab title="aria" %}
`/snapshots/failure?format=aria` returns the accessibility tree, in the format of Playwright's `ariaSnapshot()`. Roles and names come from the HTML only, so an element that a stylesheet hides still shows:

```yaml
- form
  - textbox "Discount code": save10
  - button "Apply"
  - status
    - text: SAVE10 applied: 10% off
- text: Total
- text: $183.60
- button "Pay now"
```

{% endtab %}

{% tab title="dom" %}
`/snapshots/failure?format=dom` returns the HTML of the page as plain text, to search or compare. Part of it:

```html
<DT>Discount</DT>
<DD id="discount">−$22.95</DD>
<DT>Total</DT>
<DD id="total">$183.60</DD>
```

{% endtab %}

{% tab title="html" %}
`/snapshots/failure?format=html` returns a page that a browser opens with the styles from the trace. The trace API removes the scripts, so buttons and links do nothing. Opened in a browser:

<figure><img src="https://3745692499-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FqmFDEiUa9mr11LUlxDnt%2Fuploads%2Fgit-blob-740437e4360149b9cd165dedd62c84370446ebed%2Ftrace-snapshot-html.png?alt=media" alt="The checkout page rebuilt from the DOM snapshot at the failure: save10 in the discount field, SAVE10 applied: 10% off, a discount of −$22.95 and a total of $183.60"><figcaption><p><code>/snapshots/failure?format=html</code>: the page when the test failed, opened in a browser</p></figcaption></figure>
{% endtab %}
{% endtabs %}

## Network requests

| Route                            | Returns                      |
| -------------------------------- | ---------------------------- |
| `/requests`                      | The requests the page made   |
| `/requests/{index}`              | One request                  |
| `/requests/{index}/body`         | The body the server returned |
| `/requests/{index}/request-body` | The body the page sent       |

| Parameter     | Values                                                                                                                                                                                                      |
| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `status`      | `4xx`, `5xx`, `failed`, or a status code such as `404`. `failed` is a request that got no response, or a 4xx or 5xx response.                                                                               |
| `url`         | Text that the URL contains                                                                                                                                                                                  |
| `requestBody` | Text that the body the page sent contains, such as a GraphQL operation name. Up to 1000 characters. When the bodies to search are over 32 MB together, it returns 422: filter with `url` or `status` first. |
| `format`      | `json` (default) or `har`: a HAR 1.2 file without bodies, which opens in the browser's developer tools                                                                                                      |

`/requests?url=app.js`, the checkout session:

```json
[{ "index": 2, "method": "GET", "url": "http://localhost:4183/app.js", "status": 200, "statusText": "OK",
   "mimeType": "application/javascript; charset=UTF-8", "bodySize": -1, "bodySha1": null, "requestBodySha1": null,
   "startedDateTime": "2026-10-09T06:15:53.396Z", "durationMs": 6.015, "monotonicTime": 647.048 }]
```

`/requests/2` returns the same request as one object. `bodySha1` is `null` because the trace has no body for this response, so `/requests/2/body` returns 404.

In the failed test, every GraphQL call goes to the same `/graphql` URL, so `/requests?requestBody=ApplyDiscount` finds the call by the operation name it sent:

```json
[{ "index": 7, "method": "POST", "url": "http://127.0.0.1:4197/graphql", "status": 200, ... }]
```

Then `/requests/7/request-body` and `/requests/7/body`:

```json
{"query": "mutation ApplyDiscount($code: String!) { applyDiscount(code: $code) { code percent discount total } }", "variables": {"code": "save10"}}
{"data": {"applyDiscount": {"code": "SAVE10", "percent": 10, "discount": 2295, "total": 18360}}}
```

The server sent a total of `18360` cents: the subtotal minus the discount, twice. The bug is in the server, not in the page.

`/requests?format=har`, the checkout session, shortened:

```json
{
  "log": {
    "version": "1.2",
    "creator": { "name": "currents-trace-api", "version": "1" },
    "entries": [
      {
        "startedDateTime": "2026-10-09T06:15:53.388Z",
        "time": 5.533,
        "request": { "method": "GET", "url": "http://localhost:4183/", "httpVersion": "HTTP/1.1", "headers": [{ "name": "Host", "value": "localhost:4183" }] }
      }
    ]
  }
}
```

A wrong `status` returns 400 with the values it takes: `{"error":"status must be 4xx, 5xx, failed, or a 3-digit code"}`.

## Attachments

| Route               | Returns                                                                                                                                          |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `/attachments`      | The files the test saved in the trace, such as the video, the screenshot and `error-context`, with the name, content type and SHA-1 hash of each |
| `/attachments/{id}` | One file, by its hash or its name, with the file's own content type                                                                              |

| Parameter | Values                                                                                 |
| --------- | -------------------------------------------------------------------------------------- |
| `name`    | On `/attachments`: text that the file name contains, such as `/attachments?name=error` |

| Response header                          | Value                                                                    |
| ---------------------------------------- | ------------------------------------------------------------------------ |
| `x-attachment-name`, `x-attachment-sha1` | On `/attachments/{id}`: the name and the SHA-1 hash of the file returned |

A retry can save a file with the same name again, so a name returns the last file with that name.

`/attachments`, the failed test. `callId` is the step that saved the file:

```json
[
  { "name": "video", "contentType": "video/webm", "sha1": "7f4c1aa21fc4f772f8392b90f1b2d8fffd6eeeeb",
    "file": "attachments/7f4c1aa21fc4f772f8392b90f1b2d8fffd6eeeeb", "callId": "fixture@45" },
  { "name": "error-context", "contentType": "text/markdown", "sha1": "1aeff453f814f2d988212f6cb6e0ee5d63f0c26f",
    "file": "attachments/1aeff453f814f2d988212f6cb6e0ee5d63f0c26f", "callId": "attach@a0bd6f912f21848fc9fc6fe2c64c4611" },
  { "name": "screenshot", "contentType": "image/png", "sha1": "a8fae78a7904ebca24b0a25ec23903eab7a3a4dc",
    "file": "attachments/a8fae78a7904ebca24b0a25ec23903eab7a3a4dc", "callId": "hook@43" }
]
```

`/attachments/error-context` is the failure summary that Playwright writes for an agent: the test name, the error, the element at the failure as an accessibility tree, and the test source. The failed test, shortened:

````markdown
# Test info

- Name: checkout.spec.ts >> SAVE10 takes 10% off the total
- Location: tests/checkout.spec.ts:23:1

# Error details

```
Error: expect(locator).toHaveText(expected) failed

Locator:  locator('#total')
Expected: "$206.55"
Received: "$183.60"
```

```yaml
- definition: $183.60
```

# Test source

```ts
  23 | test("SAVE10 takes 10% off the total", async ({ page }) => {
  24 |   await page.getByLabel("Discount code").fill("save10");
  25 |   await page.getByRole("button", { name: "Apply" }).click();
> 26 |   await expect(page.locator("#total")).toHaveText("$206.55");
     |                                        ^ Error: expect(locator).toHaveText(expected) failed
```
````

The checkout session has no files, so its `/attachments` returns `[]`.

## Trace zip

| Route       | Returns                       |
| ----------- | ----------------------------- |
| `/download` | The trace zip, as `trace.zip` |

To open it in Playwright's trace viewer, give the viewer the link: `https://trace.playwright.dev/?trace=<trace API link>/download`.

## Placeholders

`/filmstrip`, `/frames/failure` and `/snapshots/failure?format=html` take `placeholder=1`. With it, they return a grey image or a short page with status 200 instead of an error. Use it for images in a pull request comment, so that they do not break after the link expires.

| Response header | Value                                                                                                                                                                                                                 |
| --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `x-placeholder` | Why a placeholder was returned. `notFound`: the link is wrong or expired. `routeError`: the trace has nothing to show, such as no screen frames, or a parameter is wrong. `unavailable`: the trace could not be read. |

A filmstrip of an expired link, `/filmstrip?placeholder=1&width=640`:

<figure><img src="https://3745692499-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FqmFDEiUa9mr11LUlxDnt%2Fuploads%2Fgit-blob-d8d302619a41673f2c3b450a25bcd4cd6a9c79d2%2Ftrace-placeholder-expired.svg?alt=media" alt="A grey box with the text This link has expired" width="584"><figcaption><p><code>/filmstrip?placeholder=1&#x26;width=640</code> after the link expires</p></figcaption></figure>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.currents.dev/ai/reference/trace-api.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
