# Requests API

> Search a bucket's captured requests, read one in full with its spans and timings, find what ran beside it, and generate AI fix and performance prompts.

Source: https://www.apitraffic.io/docs/api-reference/requests

Every request your SDK captures, inbound to your API or outbound from it, is stored in a bucket. These operations search those requests, return one in full, and build the prompts the app's **Fix with AI** and waterfall views use. For searching in the app, see [Search requests](https://www.apitraffic.io/docs/traffic/search) and [Request details](https://www.apitraffic.io/docs/traffic/request-details).

**Permissions:** any member, or a `user` or `administrator` API token. Requests in the [sample bucket](https://www.apitraffic.io/docs/sample-data) can be read like your own.

## The request object

- **sid (string, required)**:
  The request's identifier (`req_` followed by 27 letters and digits).

- **bucketSid (string, required)**:
  The bucket it was captured in.

- **environmentSid (string | null)**:
  The environment it was captured in.

- **contextSid (string | null)**:
  Links an outbound request to the inbound request that made it.

- **direction (string, required)**:
  `in` for a request your API received, `out` for a call your API made.

- **createdAt (string)**:
  When the request started (ISO 8601).

- **receivedAt (string)**:
  When your server received the request (ISO 8601), as your SDK reported it. If the reported time is more than 1 minute ahead of or 5 minutes behind when ApiTraffic received the request (for example, the server's clock is wrong), or no time was reported, this is when ApiTraffic received it. For traffic sent through the relay, this is when the relay received it. Requests captured before this behavior was introduced (late 2026) show when ApiTraffic received them.

- **note (string | null, required)**:
  A note added to the request, if any.

- **endpoint (string | null)**:
  The endpoint pattern the request belongs to, for example `/v1/orders/{order_id}`.

- **endpointSource (string | null)**:
  How the endpoint was found: `framework` (your framework's router), `rule` (an [endpoint rule](https://www.apitraffic.io/docs/data/endpoint-rules)) or `auto` (learned from paths).

- **endpointKind (string | null)**:
  `rest`, `graphql`, `mcp` or `jsonrpc`.

- **endpointConfidence (number | null)**:
  How confident automatic detection was, from 0 to 1.

- **request (object, required)**:
  What was sent.

**request**

- **method (string)**: HTTP method.

- **host (string)**: Host name.

- **port (number | null)**: Port.

- **path (string)**: Path, without the query string.

- **url (string)**: The full URL.

- **queryString (object)**: Query parameters.

- **headers (object)**: Headers, after redaction.

- **body (any)**: The body, after redaction. Only returned by [Get request](#get-request).

- **contentType (string | null)**: Content type.

- **size (number | null)**: Body size in bytes.

- **response (object | null)**:
  What came back: `statusCode`, `headers`, `body` (only from [Get request](#get-request)), `contentType` and `size`.

- **timings (object | null)**:
  `duration` in milliseconds (for a streaming response, how long it stayed open), `firstByte`, and for outbound calls the connection timestamps and `phases` (`dns`, `tcp`, `tls`, `wait`, `request`, `firstByte`, `download`, `total`).

- **firewall (object)**:
  `blocked`: whether the [firewall](https://www.apitraffic.io/docs/waf/overview) blocked the request.

- **tags (object | null, required)**:
  Custom tags your code attached.

- **spans (object[] | null)**:
  [APM](https://www.apitraffic.io/docs/apm/overview) spans: database, cache, outbound HTTP and queue operations inside the request.

**span**

- **id (string)**: Span identifier.

- **parentId (string | null)**: Parent span, for nested spans.

- **type (string)**: `db.query`, `redis`, `cache`, `http.out`, `queue`, `rpc`, `graphql` or `custom`.

- **name (string)**: A short label, for example `SELECT orders`.

- **fingerprint (string | null)**: The operation's fingerprint (`fpr_…`), shared by every run of the same operation. Use it with the [Spans API](https://www.apitraffic.io/docs/api-reference/spans).

- **startOffsetUs (number)**: Start, in microseconds from the start of the request.

- **durationUs (number)**: Duration in microseconds.

- **ok (boolean)**: Whether the operation succeeded.

- **meta (object)**: Detail by type: `statement`, `system`, `db`, `host`, `rows`, `method`, `statusCode`, `command`, `key`, `bodyCaptured`.

- **textWithheld (boolean)**: `true` when the query text was removed because the account does not store statement text.

- **metrics (object | null)**:
  Per-request APM totals: `count` and `timeMs` for `db`, `redis`, `cache`, `httpOut`, `queue` and `rpc`, plus `spanCount` and `spansDropped`.

- **instance (object | null)**:
  The server that handled the request: `sid`, `machineId`, and its event-loop delay, utilization, in-flight requests and heap use when the request arrived.

- **streaming (boolean)**:
  `true` for a long-lived response (server-sent events, or an endpoint rule marked as a stream).

- **bodiesExpired (boolean)**:
  `true` when the bodies passed the plan's body retention period and are no longer stored. `expiredBodies` says which (`request`, `response`).

- **bodiesUnavailable (boolean)**:
  `true` when the bodies could not be read this time. They have not expired; try again.

## List requests

`GET https://api.apitraffic.io/v1/accounts/{accountSid}/buckets/{bucketSid}/requests`

Searches the requests in a bucket, newest first. Filter with `criteria` (the same syntax as the search bar), a time range or a stream view, and page with the `from` cursor. List results leave out request and response bodies; call [Get request](#get-request) for one with its bodies.

### Path parameters

- **accountSid (path, string, required)**:
  The account identifier.

- **bucketSid (path, string, required)**:
  The bucket identifier.

### Query parameters

- **environmentSid (query, string)**:
  Only requests from this environment. Without it, every environment is searched.

- **criteria (query, string)**:
  A filter in the [search syntax](https://www.apitraffic.io/docs/traffic/search), for example `status_code >= 500 AND url_path like "/v1/payments/*"`. URL-encode it. Conditions on request or response bodies need a plan that includes body search.

- **streamViewSid (query, string)**:
  Use the criteria of a stream view instead of `criteria`.

- **startTime (query, string)**:
  Only requests at or after this time (ISO 8601). Without it, the search reaches back to the start of your plan's retention.

- **endTime (query, string)**:
  Only requests at or before this time (ISO 8601). Defaults to now.

- **limit (query, number, default 25)**:
  Requests per page, 1 to 1000.

- **from (query, string)**:
  The `from` value from the previous page, to get the next one.

- **includeProperties (query, boolean, default true)**:
  Include `properties`: the header names and tags seen in the results, with counts, for building filters. Pass `false` when you only need the records; the response is faster. To show both without the records waiting, pass `false` here and call [List request properties](#list-request-properties) beside it.

### Response

- **hasMore (boolean, required)**:
  Whether another page may exist.

- **from (string | null, required)**:
  The cursor for the next page. Pass it as `from`.

- **properties (object | null)**:
  `requestHeaders`, `responseHeaders` and `tags`: arrays of `key` and `count`. `null` when `includeProperties=false`.

- **records (object[], required)**:
  [Request objects](#the-request-object), without bodies.

- **degraded (boolean)**:
  Present and `true` when part of the response could not be read.

- **failed (string[])**:
  What could not be read: `properties`, or `archive` (an older time slice; the page is partial, `hasMore` is `true`, and `from` continues after its last record).

```bash cURL
curl -G https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/buckets/k3m9p2x/requests \
  -H "Authorization: Bearer $APITRAFFIC_TOKEN" \
  --data-urlencode 'criteria=status_code >= 500 AND url_path like "/v1/payments/*"' \
  --data-urlencode 'startTime=2026-10-19T14:00:00.000Z' \
  --data-urlencode 'endTime=2026-10-19T14:40:00.000Z' \
  --data-urlencode 'limit=50' \
  --data-urlencode 'includeProperties=false'
```

```js Node.js
const accountSid = 'acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa';
const base = `https://api.apitraffic.io/v1/accounts/${accountSid}/buckets/k3m9p2x/requests`;
const all = [];
let from;
do {
  const params = new URLSearchParams({
    criteria: 'status_code >= 500 AND url_path like "/v1/payments/*"',
    startTime: '2026-10-19T14:00:00.000Z',
    endTime: '2026-10-19T14:40:00.000Z',
    limit: '100',
    includeProperties: 'false',
  });
  if (from) params.set('from', from);
  const response = await fetch(`${base}?${params}`, {
    headers: { Authorization: `Bearer ${process.env.APITRAFFIC_TOKEN}` },
  });
  const page = await response.json();
  all.push(...page.records);
  from = page.hasMore ? page.from : undefined;
} while (from);
```

```json 200
{
  "hasMore": true,
  "from": "eyJkdCI6IjIwMjYtMTAtMTlUMTQ6MjE6MDcuNDEyWiJ9",
  "properties": null,
  "records": [
    {
      "sid": "req_2nA8fK3pQ7xV1mZ5tR9wB4cL6hY",
      "bucketSid": "k3m9p2x",
      "environmentSid": "prd7k2",
      "contextSid": null,
      "direction": "in",
      "note": null,
      "createdAt": "2026-10-19T14:21:07.412Z",
      "receivedAt": "2026-10-19T14:21:08.020Z",
      "endpoint": "/v1/payments/{payment_id}/capture",
      "endpointSource": "framework",
      "endpointKind": "rest",
      "firewall": { "blocked": false },
      "request": {
        "host": "api.acme-store.example",
        "method": "POST",
        "path": "/v1/payments/pi_3f9a1c7e2b4d6a/capture",
        "port": 443,
        "url": "https://api.acme-store.example/v1/payments/pi_3f9a1c7e2b4d6a/capture",
        "queryString": {},
        "headers": { "content-type": "application/json" },
        "contentType": "application/json",
        "size": 64
      },
      "response": {
        "statusCode": 502,
        "headers": { "content-type": "application/json" },
        "contentType": "application/json",
        "size": 118
      },
      "timings": { "duration": 4012, "firstByte": 4010 },
      "tags": null,
      "metrics": {
        "db": { "count": 2, "timeMs": 6 },
        "httpOut": { "count": 1, "timeMs": 3995 },
        "spanCount": 3,
        "spansDropped": 0
      }
    }
  ]
}
```

## List request properties

`GET https://api.apitraffic.io/v1/accounts/{accountSid}/buckets/{bucketSid}/requestProperties`

Returns the kind of names the `properties` of [List requests](#list-requests) carries, on their own: the request header, response header and tag names seen in the requests a search matches, with counts, for building filters. The names come from a recent window (the last day by default) ending at `endTime`, and are refreshed about once a minute. Send it the same query as the list, alongside it, so the records never wait for the names.

### Path parameters

- **accountSid (path, string, required)**:
  The account identifier.

- **bucketSid (path, string, required)**:
  The bucket identifier.

### Query parameters

- **environmentSid (query, string)**:
  Only requests from this environment.

- **criteria (query, string)**:
  A filter in the [search syntax](https://www.apitraffic.io/docs/traffic/search), as for the list. URL-encode it.

- **streamViewSid (query, string)**:
  Use the criteria of a stream view instead of `criteria`.

- **endTime (query, string)**:
  End of the window the names are read from (ISO 8601). Defaults to now. `startTime` and the list's paging parameters are accepted too, so the list's query can be sent as it is.

### Response

- **properties (object | null, required)**:
  `requestHeaders`, `responseHeaders` and `tags`: arrays of `key` and `count`, the commonest first. `null` when they could not be read.

- **degraded (boolean)**:
  Present and `true` when the names could not be read; `failed` is `["properties"]`.

```bash cURL
curl -G https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/buckets/k3m9p2x/requestProperties \
  -H "Authorization: Bearer $APITRAFFIC_TOKEN" \
  --data-urlencode 'criteria=status_code >= 500' \
  --data-urlencode 'endTime=2026-10-19T14:40:00.000Z'
```

```json 200
{
  "properties": {
    "requestHeaders": [
      { "key": "content-type", "count": 1840 },
      { "key": "x-request-id", "count": 1838 }
    ],
    "responseHeaders": [
      { "key": "content-type", "count": 1840 }
    ],
    "tags": [
      { "key": "tenant", "count": 912 }
    ]
  }
}
```

## Get request

`GET https://api.apitraffic.io/v1/accounts/{accountSid}/buckets/{bucketSid}/requests/{requestSid}`

Returns one request in full, with its headers, bodies (after redaction), timings and spans.

### Path parameters

- **accountSid (path, string, required)**:
  The account identifier.

- **bucketSid (path, string, required)**:
  The bucket identifier.

- **requestSid (path, string, required)**:
  The request identifier (`req_…`).

### Response

A [request object](#the-request-object), including `request.body` and `response.body`.

```bash cURL
curl https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/buckets/k3m9p2x/requests/req_2nA8fK3pQ7xV1mZ5tR9wB4cL6hY \
  -H "Authorization: Bearer $APITRAFFIC_TOKEN"
```

```js Node.js
const accountSid = 'acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa';
const requestSid = 'req_2nA8fK3pQ7xV1mZ5tR9wB4cL6hY';
const response = await fetch(
  `https://api.apitraffic.io/v1/accounts/${accountSid}/buckets/k3m9p2x/requests/${requestSid}`,
  { headers: { Authorization: `Bearer ${process.env.APITRAFFIC_TOKEN}` } },
);
const captured = await response.json();
console.log(captured.response.statusCode, captured.spans?.length);
```

```json 200
{
  "sid": "req_2nA8fK3pQ7xV1mZ5tR9wB4cL6hY",
  "bucketSid": "k3m9p2x",
  "environmentSid": "prd7k2",
  "contextSid": null,
  "direction": "in",
  "note": null,
  "createdAt": "2026-10-19T14:21:07.412Z",
  "receivedAt": "2026-10-19T14:21:08.020Z",
  "endpoint": "/v1/payments/{payment_id}/capture",
  "endpointSource": "framework",
  "endpointKind": "rest",
  "firewall": { "blocked": false },
  "request": {
    "host": "api.acme-store.example",
    "method": "POST",
    "path": "/v1/payments/pi_3f9a1c7e2b4d6a/capture",
    "port": 443,
    "url": "https://api.acme-store.example/v1/payments/pi_3f9a1c7e2b4d6a/capture",
    "queryString": {},
    "headers": { "content-type": "application/json", "authorization": "[REDACTED]" },
    "body": { "amount": 8450, "currency": "usd" },
    "contentType": "application/json",
    "size": 64
  },
  "response": {
    "statusCode": 502,
    "headers": { "content-type": "application/json" },
    "body": { "error": "upstream_timeout", "message": "Payment provider did not respond" },
    "contentType": "application/json",
    "size": 118
  },
  "timings": { "duration": 4012, "firstByte": 4010 },
  "tags": null,
  "spans": [
    {
      "id": "spn_01",
      "parentId": null,
      "type": "db.query",
      "name": "SELECT payments",
      "fingerprint": "fpr_8c1d4e7a9b2f3c6d",
      "startOffsetUs": 1200,
      "durationUs": 3100,
      "ok": true,
      "meta": { "system": "postgresql", "db": "acme_store", "statement": "SELECT * FROM payments WHERE id = $1", "rows": 1 }
    },
    {
      "id": "spn_02",
      "parentId": null,
      "type": "http.out",
      "name": "POST payments.acme-pay.example",
      "fingerprint": "fpr_2a7e9c4b1d8f6e3a",
      "startOffsetUs": 5400,
      "durationUs": 3995000,
      "ok": false,
      "meta": { "method": "POST", "host": "payments.acme-pay.example", "statusCode": 504 }
    }
  ],
  "metrics": {
    "db": { "count": 2, "timeMs": 6 },
    "httpOut": { "count": 1, "timeMs": 3995 },
    "spanCount": 3,
    "spansDropped": 0
  },
  "instance": { "sid": "ins_acme-api-1", "machineId": "m_7f3a", "eventLoopDelayMs": 2, "inFlight": 14 }
}
```

## Get concurrent requests

`GET https://api.apitraffic.io/v1/accounts/{accountSid}/buckets/{bucketSid}/requests/{requestSid}/concurrent`

Lists the requests that were running on the same server while this one was in flight, ranked by the overlapping time they spent working rather than waiting on I/O. Use it to find a noisy neighbor behind a slow request. Only one server is compared, so every time is on the same clock.

Requests captured by SDK versions that do not report which server handled them return `available: false` and no neighbors.

### Path parameters

- **accountSid (path, string, required)**:
  The account identifier.

- **bucketSid (path, string, required)**:
  The bucket identifier.

- **requestSid (path, string, required)**:
  The request identifier.

### Query parameters

- **limit (query, number, default 50)**:
  Most neighbors returned, 1 to 200.

- **lookbackMinutes (query, number, default 1)**:
  How far before this request to look for requests that were still running, 1 to 60. Neighbors that started earlier are not shown.

### Response

- **requestSid (string)**:
  The request you asked about.

- **instanceSid (string | null)**:
  The server it ran on. `null` when not reported.

- **available (boolean)**:
  `false` when the request carries no server attribution.

- **lookbackMs (number)**:
  The window that was scanned, in milliseconds.

- **endpoints (object[])**:
  Neighbors grouped by endpoint: `endpoint`, `method`, `requestCount`, `totalOverlapMs`, `maxOverlapMs` and `overlappingSelfTimeMs`.

- **requests (object[])**:
  The neighbors: `sid`, `dt`, `method`, `endpoint`, `statusCode`, `durationMs`, `overlapMs` and `overlappingSelfTimeMs`.

```bash cURL
curl "https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/buckets/k3m9p2x/requests/req_2nA8fK3pQ7xV1mZ5tR9wB4cL6hY/concurrent?limit=20" \
  -H "Authorization: Bearer $APITRAFFIC_TOKEN"
```

```js Node.js
const accountSid = 'acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa';
const requestSid = 'req_2nA8fK3pQ7xV1mZ5tR9wB4cL6hY';
const response = await fetch(
  `https://api.apitraffic.io/v1/accounts/${accountSid}/buckets/k3m9p2x/requests/${requestSid}/concurrent?limit=20`,
  { headers: { Authorization: `Bearer ${process.env.APITRAFFIC_TOKEN}` } },
);
const { endpoints } = await response.json();
```

```json 200
{
  "requestSid": "req_2nA8fK3pQ7xV1mZ5tR9wB4cL6hY",
  "instanceSid": "ins_acme-api-1",
  "available": true,
  "lookbackMs": 60000,
  "endpoints": [
    {
      "endpoint": "/v1/orders",
      "method": "GET",
      "requestCount": 6,
      "totalOverlapMs": 2410,
      "maxOverlapMs": 820,
      "overlappingSelfTimeMs": 1530
    }
  ],
  "requests": [
    {
      "sid": "req_2xB7nM4kP9qR1tV6wZ3cL8hY5fG",
      "dt": "2026-10-19T14:21:07.100Z",
      "method": "GET",
      "endpoint": "/v1/orders",
      "statusCode": 200,
      "durationMs": 840,
      "overlapMs": 820,
      "overlappingSelfTimeMs": 610
    }
  ]
}
```

## Get code context

`GET https://api.apitraffic.io/v1/accounts/{accountSid}/buckets/{bucketSid}/requests/{requestSid}/code-context`

Finds the repository and commit that were deployed when the request was captured, from the most recent deploy [event](https://www.apitraffic.io/docs/api-reference/events) with a usable commit before it. The app uses this to link span code locations to the code as it ran.

**Plan:** needs a plan that includes the **Git integration**.

### Path parameters

- **accountSid (path, string, required)**:
  The account identifier.

- **bucketSid (path, string, required)**:
  The bucket identifier.

- **requestSid (path, string, required)**:
  The request identifier.

### Query parameters

- **environmentSid (query, string)**:
  Only consider deploy markers for this environment.

- **lookbackMinutes (query, number, default 43200)**:
  How far back to look for the deploy in effect, 1 to 129600 minutes. Defaults to 30 days.

### Response

- **requestSid (string | null)**:
  The request you asked about.

- **bucketSid (string | null)**:
  Its bucket.

- **context (object | null, required)**:
  `null` when no deploy marker with a commit precedes the request. Otherwise `provider`, `repoFullName`, `sha`, `branch`, `deployedAt`, `eventSid` and `fileUrlTemplate` (a link pattern for files at that commit).

```bash cURL
curl https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/buckets/k3m9p2x/requests/req_2nA8fK3pQ7xV1mZ5tR9wB4cL6hY/code-context \
  -H "Authorization: Bearer $APITRAFFIC_TOKEN"
```

```js Node.js
const accountSid = 'acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa';
const requestSid = 'req_2nA8fK3pQ7xV1mZ5tR9wB4cL6hY';
const response = await fetch(
  `https://api.apitraffic.io/v1/accounts/${accountSid}/buckets/k3m9p2x/requests/${requestSid}/code-context`,
  { headers: { Authorization: `Bearer ${process.env.APITRAFFIC_TOKEN}` } },
);
const { context } = await response.json();
```

```json 200
{
  "requestSid": "req_2nA8fK3pQ7xV1mZ5tR9wB4cL6hY",
  "bucketSid": "k3m9p2x",
  "context": {
    "provider": "github",
    "repoFullName": "acme/acme-store-api",
    "sha": "4e1b9c7a2d5f8e3b6a0c1d4f7e2a9b5c8d3e6f1a",
    "branch": "main",
    "deployedAt": "2026-10-19T10:00:00.000Z",
    "eventSid": "evt_2tG5yH7uJ9iK1oL3pZ6xC8vB4nM",
    "fileUrlTemplate": "https://github.com/acme/acme-store-api/blob/4e1b9c7a2d5f8e3b6a0c1d4f7e2a9b5c8d3e6f1a/{path}#L{line}"
  }
}
```

## Get fix prompt

`GET https://api.apitraffic.io/v1/accounts/{accountSid}/buckets/{bucketSid}/requests/{requestSid}/fix-prompt`

Builds a prompt you can paste into an AI coding agent to find the cause of a failing request in your code. It includes the request, the error, and the deploys and commits that landed shortly before the failure.

**Plan:** needs a plan that includes **AI diagnoses**. Each call counts toward the plan's monthly AI diagnoses allowance; when it is used up, the API answers `429` with code `2222`.

### Path parameters

- **accountSid (path, string, required)**:
  The account identifier.

- **bucketSid (path, string, required)**:
  The bucket identifier.

- **requestSid (path, string, required)**:
  The request identifier.

### Query parameters

- **lookbackMinutes (query, number, default 180)**:
  How far back to look for deploys, 1 to 10080 minutes.

### Response

- **prompt (string, required)**:
  The prompt, ready to paste.

- **deploys (object[], required)**:
  Deploy markers that started before the failure, newest first: `eventSid`, `type`, `name`, `source`, `startedAt`, `minutesBeforeOnset`, and the commit details read from the event's metadata (`repoFullName`, `branch`, `headSha`, `url`, `tag`, `releaseName`, `pullRequest`, `commits`).

- **requestSid (string | null)**:
  The request.

- **bucketSid (string | null)**:
  Its bucket.

- **endpoint (string | null)**:
  The endpoint.

- **method (string | null)**:
  The HTTP method.

- **statusCode (number | null)**:
  The response status.

- **direction (string | null)**:
  `in` or `out`.

- **errorSignature (string | null)**:
  A short signature of the error.

- **firstSeen (string | null)**:
  When this error was first seen.

```bash cURL
curl https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/buckets/k3m9p2x/requests/req_2nA8fK3pQ7xV1mZ5tR9wB4cL6hY/fix-prompt \
  -H "Authorization: Bearer $APITRAFFIC_TOKEN"
```

```js Node.js
const accountSid = 'acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa';
const requestSid = 'req_2nA8fK3pQ7xV1mZ5tR9wB4cL6hY';
const response = await fetch(
  `https://api.apitraffic.io/v1/accounts/${accountSid}/buckets/k3m9p2x/requests/${requestSid}/fix-prompt`,
  { headers: { Authorization: `Bearer ${process.env.APITRAFFIC_TOKEN}` } },
);
const { prompt } = await response.json();
```

```json 200
{
  "requestSid": "req_2nA8fK3pQ7xV1mZ5tR9wB4cL6hY",
  "bucketSid": "k3m9p2x",
  "endpoint": "/v1/payments/{payment_id}/capture",
  "method": "POST",
  "statusCode": 502,
  "direction": "in",
  "errorSignature": "502 upstream_timeout",
  "firstSeen": "2026-10-19T14:00:12.000Z",
  "deploys": [
    {
      "eventSid": "evt_2tG5yH7uJ9iK1oL3pZ6xC8vB4nM",
      "type": "deployment",
      "name": "deploy v2026.10.19",
      "source": "ci",
      "startedAt": "2026-10-19T10:00:00.000Z",
      "minutesBeforeOnset": 240,
      "repoFullName": null,
      "branch": "main",
      "headSha": "4e1b9c7a2d5f8e3b6a0c1d4f7e2a9b5c8d3e6f1a",
      "url": null,
      "tag": null,
      "releaseName": null,
      "pullRequest": null,
      "commits": []
    }
  ],
  "prompt": "A request to POST /v1/payments/{payment_id}/capture failed with 502 ..."
}
```

## Get waterfall prompt

`GET https://api.apitraffic.io/v1/accounts/{accountSid}/buckets/{bucketSid}/requests/{requestSid}/waterfall-prompt`

Builds a prompt about where a request's time went and how to make it faster. It carries every span with its timing, code location and call stack, the deployed commit, and precomputed idle gaps and repeated operations (such as an N+1 query). Captured parameter values are never included.

**Plan:** needs **AI diagnoses**, and counts toward the monthly allowance like [Get fix prompt](#get-fix-prompt).

### Path parameters

- **accountSid (path, string, required)**:
  The account identifier.

- **bucketSid (path, string, required)**:
  The bucket identifier.

- **requestSid (path, string, required)**:
  The request identifier.

### Query parameters

- **question (query, string)**:
  What to ask the agent, up to 2000 characters. Defaults to "How can I optimize this request?".

- **note (query, string)**:
  Why this request was picked, up to 500 characters, for example `one of the slowest calls in the period`.

- **focusSpanId (query, string)**:
  A span to mark as the one being investigated.

- **environmentSid (query, string)**:
  Only consider deploys for this environment when finding the code context.

### Response

- **prompt (string, required)**:
  The prompt, ready to paste.

- **template (string, required)**:
  The prompt with `questionSlot` where the question goes, so you can change the question without generating again.

- **questionSlot (string, required)**:
  The placeholder in `template`.

- **question (string, required)**:
  The question used.

- **suggestedQuestions (string[], required)**:
  Other questions worth asking about this request.

- **spanCount (number, required)**:
  Spans in the prompt.

- **codeContext (object | null, required)**:
  `repoFullName`, `sha` and `branch` of the deployed code, when known.

- **requestSid (string | null)**:
  The request.

- **bucketSid (string | null)**:
  Its bucket.

- **method (string | null)**:
  The HTTP method.

- **endpoint (string | null)**:
  The endpoint.

- **durationMs (number | null)**:
  The request's duration.

```bash cURL
curl -G https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/buckets/k3m9p2x/requests/req_2nA8fK3pQ7xV1mZ5tR9wB4cL6hY/waterfall-prompt \
  -H "Authorization: Bearer $APITRAFFIC_TOKEN" \
  --data-urlencode 'question=Why does this request spend so long in the database?'
```

```js Node.js
const accountSid = 'acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa';
const requestSid = 'req_2nA8fK3pQ7xV1mZ5tR9wB4cL6hY';
const params = new URLSearchParams({ question: 'Why does this request spend so long in the database?' });
const response = await fetch(
  `https://api.apitraffic.io/v1/accounts/${accountSid}/buckets/k3m9p2x/requests/${requestSid}/waterfall-prompt?${params}`,
  { headers: { Authorization: `Bearer ${process.env.APITRAFFIC_TOKEN}` } },
);
const { prompt, suggestedQuestions } = await response.json();
```

```json 200
{
  "requestSid": "req_2nA8fK3pQ7xV1mZ5tR9wB4cL6hY",
  "bucketSid": "k3m9p2x",
  "method": "GET",
  "endpoint": "/v1/orders/{order_id}",
  "durationMs": 912,
  "spanCount": 23,
  "question": "Why does this request spend so long in the database?",
  "suggestedQuestions": [
    "How can I optimize this request?",
    "Is there an N+1 query here?"
  ],
  "codeContext": {
    "repoFullName": "acme/acme-store-api",
    "sha": "4e1b9c7a2d5f8e3b6a0c1d4f7e2a9b5c8d3e6f1a",
    "branch": "main"
  },
  "prompt": "This request to GET /v1/orders/{order_id} took 912 ms ...",
  "template": "This request to GET /v1/orders/{order_id} took 912 ms ... {{QUESTION}}",
  "questionSlot": "{{QUESTION}}"
}
```

## Resend request

`POST https://api.apitraffic.io/v1/accounts/{accountSid}/buckets/{bucketSid}/requests/{requestSid}/resend`

Send an edited copy of a captured request from ApiTraffic and log the result as a new request in the
same bucket. The new request is tagged `resent` = `"true"` and `resentFrom` = the original request's
id, so `tag:resentFrom == "req_…"` finds every resend of a request. See
[Resend a request](https://www.apitraffic.io/docs/resend-request) for how it appears in the app.

> **Warning:** This sends a real request to `url`. A write method (`POST`, `PUT`, `PATCH`, `DELETE`) can create or
> change data at the destination, just as the original did.

Private, loopback and reserved destinations are refused, as are ports used by non-HTTP services.
Redirects are not followed. The whole exchange must finish within 30 seconds, and the response
is read up to 2 MB after decompression. Each account can resend 30 requests a minute.

### Path parameters

- **accountSid (path, string, required)**:
  The account identifier.

- **bucketSid (path, string, required)**:
  The bucket identifier.

- **requestSid (path, string, required)**:
  The request being resent (`req_…`).

### Headers

- **Authorization (header, string, required)**:
  Bearer token for authentication

### Request body

- **method (body, string, required)**:
  HTTP method, letters only (for example `POST`)

- **url (body, string, required)**:
  Absolute `http://` or `https://` URL to send to. Credentials in the URL (`user:pass@`) are refused.

- **headers (body, object)**:
  Header names and values. `Host`, `Content-Length` and connection headers are set from the request
  as it is sent, and are ignored here. Values must be Latin-1 with no line breaks.

- **body (body, string)**:
  Request body, sent exactly as given. Ignored for `GET` and `HEAD`.

### Response

- **requestSid (string | null)**:
  The id the new request is logged under. It appears in the request log a few seconds later.
  `null` when the request was sent but could not be logged.

- **resentFrom (string)**:
  The request this was resent from

- **logged (boolean)**:
  Whether the new request was handed to the log

- **response (object)**:
  The destination's answer: `statusCode`, `headers`, `body` (text, or `null` for a binary body,
  with `bodyOmitted: true`), `truncated` (cut short at 2 MB), `size` in bytes and `contentType`

- **timings (object)**:
  `duration` and `firstByte`, in milliseconds

### Errors

| Status | Code | When |
| --- | --- | --- |
| 400 | 1000 or 2650 | The body is missing a field (1000), or the method, URL or a header is not valid (2650) |
| 403 | 2654 | The account cannot log requests right now (subscription or plan allowance) |
| 404 | 4000 | The request does not exist in this bucket |
| 422 | 2651 | The destination is a private or reserved address, or a blocked port |
| 429 | 2653 | The account has used this minute's resends |
| 502 | 2652 | No response came back: refused, unreachable, timed out or a TLS failure |

```bash cURL
curl -X POST "https://api.apitraffic.io/v1/accounts/acc_abc123def456ghi789jkl012/buckets/bkt_xyz789uvw012rst345abc/requests/req_abc123def456ghi789jkl012mno/resend" \
  -H "Authorization: Bearer your-jwt-token" \
  -H "Content-Type: application/json" \
  -d '{
    "method": "POST",
    "url": "https://api.example.com/v1/orders?currency=eur",
    "headers": {
      "content-type": "application/json",
      "authorization": "Bearer your-api-token"
    },
    "body": "{\"sku\":\"TSHIRT-BLK-M\",\"quantity\":2}"
  }'
```

```javascript Node.js
const response = await fetch('https://api.apitraffic.io/v1/accounts/acc_abc123def456ghi789jkl012/buckets/bkt_xyz789uvw012rst345abc/requests/req_abc123def456ghi789jkl012mno/resend', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer your-jwt-token',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    method: 'POST',
    url: 'https://api.example.com/v1/orders?currency=eur',
    headers: {
      'content-type': 'application/json',
      'authorization': 'Bearer your-api-token'
    },
    body: JSON.stringify({ sku: 'TSHIRT-BLK-M', quantity: 2 })
  })
});

const result = await response.json();
console.log(result.response.statusCode, result.requestSid);
```

```json Response
{
  "requestSid": "req_2qLAzX81bQ0vWm3eTn4kHs9pLuD",
  "resentFrom": "req_abc123def456ghi789jkl012mno",
  "logged": true,
  "sentAt": "2026-10-20T15:04:05.000Z",
  "request": {
    "method": "POST",
    "url": "https://api.example.com/v1/orders?currency=eur",
    "headers": {
      "content-type": "application/json",
      "authorization": "Bearer your-api-token"
    },
    "body": "{\"sku\":\"TSHIRT-BLK-M\",\"quantity\":2}"
  },
  "response": {
    "statusCode": 201,
    "headers": {
      "content-type": "application/json"
    },
    "body": "{\"id\":\"ord_5521\",\"status\":\"confirmed\"}",
    "bodyOmitted": false,
    "truncated": false,
    "size": 38,
    "contentType": "application/json"
  },
  "timings": {
    "duration": 184,
    "firstByte": 171
  }
}
```

## Errors

| Status | Code | Meaning |
| --- | --- | --- |
| `400` | `1000` | A parameter is invalid, for example a `requestSid` in the wrong format. |
| `400` | `2007` | `criteria` could not be parsed, or uses a body condition the plan does not include. |
| `400` | `2009` | No stream view with that `streamViewSid` in this bucket. |
| `403` | `2221` | The plan does not include AI diagnoses (prompts) or the Git integration (code context). |
| `404` | `4000` | No request with that sid in this bucket. |
| `422` | `5108` | A body condition matches too many requests. Narrow the time range or add filters. |
| `429` | `2222` | The monthly AI diagnoses allowance is used up. |
| `503`, `504` | `5101` to `5109` | The search could not run right now. Retry after `Retry-After` seconds, or narrow the time range. |

## Related

- [Search and filter requests](https://www.apitraffic.io/docs/traffic/search):
    Every field and operator you can use in `criteria`.

- [Request details](https://www.apitraffic.io/docs/traffic/request-details):
    The same data in the app, with the waterfall.

- [Spans API](https://www.apitraffic.io/docs/api-reference/spans):
    Aggregate the operations inside requests.
