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.

This page as Markdown

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 and Request details.

Permissions: any member, or a user or administrator API token. Requests in the sample bucket 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) 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.

  • 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), 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 blocked the request.

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

  • spans (object[] | null): APM 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.

  • 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 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, 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 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, 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 -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
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
{
  "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 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, 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 -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
{
  "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, including request.body and response.body.

bash
curl https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/buckets/k3m9p2x/requests/req_2nA8fK3pQ7xV1mZ5tR9wB4cL6hY \
  -H "Authorization: Bearer $APITRAFFIC_TOKEN"
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
{
  "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 "https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/buckets/k3m9p2x/requests/req_2nA8fK3pQ7xV1mZ5tR9wB4cL6hY/concurrent?limit=20" \
  -H "Authorization: Bearer $APITRAFFIC_TOKEN"
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
{
  "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 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 https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/buckets/k3m9p2x/requests/req_2nA8fK3pQ7xV1mZ5tR9wB4cL6hY/code-context \
  -H "Authorization: Bearer $APITRAFFIC_TOKEN"
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
{
  "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 https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/buckets/k3m9p2x/requests/req_2nA8fK3pQ7xV1mZ5tR9wB4cL6hY/fix-prompt \
  -H "Authorization: Bearer $APITRAFFIC_TOKEN"
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
{
  "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.

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 -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
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
{
  "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 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 -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
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
{
  "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.