# Drift API

> Read and triage API drift findings, their baselines and evidencing requests, check drift scan health, and generate AI investigation prompts.

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

Drift detection learns what each endpoint normally accepts and returns (its baseline) and raises a finding when that changes, for example a field that disappears from a response, a new required parameter or a new dependency. Detection only observes; it never changes traffic. See [API drift](https://www.apitraffic.io/docs/traffic/drift) for how it works in the app.

**Plan:** drift scans run for buckets with drift detection turned on (see [Update bucket](https://www.apitraffic.io/docs/api-reference/buckets#update-bucket)) on plans that include **API drift detection**. Reading and triaging existing findings keeps working if the plan changes. **Permissions:** any member, or a `user` or `administrator` API token.

Drift is identified per endpoint and method: `/v1/orders/{order_id}` with `GET` and with `PUT` are separate.

## The drift finding object

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

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

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

- **environmentSid (string | null)**:
  The environment.

- **endpoint (string, required)**:
  The endpoint, for example `/v1/orders/{order_id}`.

- **method (string, required)**:
  The HTTP method.

- **changeType (string, required)**:
  `breaking_request`, `breaking_response`, `additive`, `behavioral`, `dependency`, `new_endpoint`, `disappeared_endpoint` or `response_body_missing`.

- **severity (string, required)**:
  `high`, `medium` or `low`. Breaking changes are `high`.

- **status (string, required)**:
  `open`, `expected`, `acknowledged` or `resolved`.

- **classification (string, required)**:
  Whether the change is explained (for example by a deploy) or not (`unknown`).

- **title (string | null)**:
  A one-line summary.

- **diff (object)**:
  Before and after detail. The shape depends on `changeType`.

- **baselineSid (string | null)**:
  The baseline the change was detected against, and `baselineVersion` its version.

- **correlatedEventSid (string | null)**:
  A deploy [event](https://www.apitraffic.io/docs/api-reference/events) that may explain the change.

- **sampleCount (number, required)**:
  Requests sampled for the finding.

- **onsetAt (string | null)**:
  When the change first appeared in traffic.

- **detectedAt (string | null)**:
  When the scan detected it.

- **createdAt (string | null)**:
  When the finding was created.

## List drift findings

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

Returns a bucket's drift findings.

### Path parameters

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

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

### Query parameters

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

- **status (query, string)**:
  `open`, `expected`, `acknowledged` or `resolved`.

- **changeType (query, string)**:
  One of the change types above.

- **endpoint (query, string)**:
  Only this endpoint, as [List endpoints](https://www.apitraffic.io/docs/api-reference/endpoints#list-endpoints) returns it. Up to 500 characters.

- **method (query, string)**:
  Only this HTTP method.

- **limit (query, integer, default 250)**:
  Findings to return, 1 to 1000.

### Response

- **hasMore (boolean, required)**:
  Whether more findings match than were returned.

- **records (object[], required)**:
  The findings, as [drift finding objects](#the-drift-finding-object).

```bash cURL
curl -G https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/buckets/k3m9p2x/driftFindings \
  -H "Authorization: Bearer $APITRAFFIC_TOKEN" \
  --data-urlencode 'status=open' \
  --data-urlencode 'endpoint=/v1/orders/{order_id}'
```

```js Node.js
const accountSid = 'acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa';
const params = new URLSearchParams({ status: 'open', endpoint: '/v1/orders/{order_id}' });
const response = await fetch(
  `https://api.apitraffic.io/v1/accounts/${accountSid}/buckets/k3m9p2x/driftFindings?${params}`,
  { headers: { Authorization: `Bearer ${process.env.APITRAFFIC_TOKEN}` } },
);
const { records } = await response.json();
```

```json 200
{
  "hasMore": false,
  "records": [
    {
      "sid": "drift_2kM4nP6qR8sT1uV3wX5yZ7aB9cD",
      "accountSid": "acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa",
      "bucketSid": "k3m9p2x",
      "environmentSid": "prd7k2",
      "endpoint": "/v1/orders/{order_id}",
      "method": "GET",
      "baselineSid": "aeb_2pQ4rS6tU8vW1xY3zA5bC7dE9fG",
      "baselineVersion": 3,
      "changeType": "breaking_response",
      "severity": "high",
      "status": "open",
      "classification": "unknown",
      "title": "fulfillment.trackingNumber is no longer returned",
      "diff": {},
      "correlatedEventSid": "evt_2tG5yH7uJ9iK1oL3pZ6xC8vB4nM",
      "sampleCount": 214,
      "detectedAt": "2026-10-19T11:15:00.000Z",
      "onsetAt": "2026-10-19T10:02:41.000Z",
      "createdAt": "2026-10-19T11:15:00.000Z"
    }
  ]
}
```

## Get drift finding

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

Returns one finding with a summary of the baseline it was detected against.

### Path parameters

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

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

- **driftSid (path, string, required)**:
  The finding's identifier (`drift_…`).

### Response

A [drift finding object](#the-drift-finding-object), plus `baseline`: a summary of the baseline, or `null`.

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

```js Node.js
const accountSid = 'acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa';
const driftSid = 'drift_2kM4nP6qR8sT1uV3wX5yZ7aB9cD';
const response = await fetch(
  `https://api.apitraffic.io/v1/accounts/${accountSid}/buckets/k3m9p2x/driftFindings/${driftSid}`,
  { headers: { Authorization: `Bearer ${process.env.APITRAFFIC_TOKEN}` } },
);
const finding = await response.json();
```

```json 200
{
  "sid": "drift_2kM4nP6qR8sT1uV3wX5yZ7aB9cD",
  "accountSid": "acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa",
  "bucketSid": "k3m9p2x",
  "environmentSid": "prd7k2",
  "endpoint": "/v1/orders/{order_id}",
  "method": "GET",
  "baselineSid": "aeb_2pQ4rS6tU8vW1xY3zA5bC7dE9fG",
  "baselineVersion": 3,
  "changeType": "breaking_response",
  "severity": "high",
  "status": "open",
  "classification": "unknown",
  "title": "fulfillment.trackingNumber is no longer returned",
  "diff": {},
  "correlatedEventSid": "evt_2tG5yH7uJ9iK1oL3pZ6xC8vB4nM",
  "sampleCount": 214,
  "detectedAt": "2026-10-19T11:15:00.000Z",
  "onsetAt": "2026-10-19T10:02:41.000Z",
  "createdAt": "2026-10-19T11:15:00.000Z",
  "baseline": {}
}
```

The example shortens `diff` and `baseline`.

## Update drift finding

`PATCH https://api.apitraffic.io/v1/accounts/{accountSid}/buckets/{bucketSid}/driftFindings/{driftSid}`

Changes a finding's triage status. Mark a change you meant to make as `expected`, one you are looking at as `acknowledged`, and one that is fixed as `resolved`.

### Path parameters

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

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

- **driftSid (path, string, required)**:
  The finding's identifier.

### Body parameters

- **status (body, string, required)**:
  `open`, `expected`, `acknowledged` or `resolved`.

### Response

The updated [drift finding object](#the-drift-finding-object).

```bash cURL
curl -X PATCH https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/buckets/k3m9p2x/driftFindings/drift_2kM4nP6qR8sT1uV3wX5yZ7aB9cD \
  -H "Authorization: Bearer $APITRAFFIC_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "status": "acknowledged" }'
```

```js Node.js
const accountSid = 'acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa';
const driftSid = 'drift_2kM4nP6qR8sT1uV3wX5yZ7aB9cD';
const response = await fetch(
  `https://api.apitraffic.io/v1/accounts/${accountSid}/buckets/k3m9p2x/driftFindings/${driftSid}`,
  {
    method: 'PATCH',
    headers: {
      Authorization: `Bearer ${process.env.APITRAFFIC_TOKEN}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ status: 'acknowledged' }),
  },
);
const finding = await response.json();
```

```json 200
{
  "sid": "drift_2kM4nP6qR8sT1uV3wX5yZ7aB9cD",
  "accountSid": "acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa",
  "bucketSid": "k3m9p2x",
  "environmentSid": "prd7k2",
  "endpoint": "/v1/orders/{order_id}",
  "method": "GET",
  "baselineSid": "aeb_2pQ4rS6tU8vW1xY3zA5bC7dE9fG",
  "baselineVersion": 3,
  "changeType": "breaking_response",
  "severity": "high",
  "status": "acknowledged",
  "classification": "unknown",
  "title": "fulfillment.trackingNumber is no longer returned",
  "diff": {},
  "correlatedEventSid": "evt_2tG5yH7uJ9iK1oL3pZ6xC8vB4nM",
  "sampleCount": 214,
  "detectedAt": "2026-10-19T11:15:00.000Z",
  "onsetAt": "2026-10-19T10:02:41.000Z",
  "createdAt": "2026-10-19T11:15:00.000Z"
}
```

## List drift finding requests

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

Lists the captured requests that show the change. Open one with [Get request](https://www.apitraffic.io/docs/api-reference/requests#get-request).

### Path parameters

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

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

- **driftSid (path, string, required)**:
  The finding's identifier.

### Response

- **hasMore (boolean, required)**:
  Whether more requests exist.

- **records (object[], required)**:
  One entry per request: `sid`, `driftSid`, `requestSid`, `observedAt` and `role`: `exemplar` (a typical example), `onset` (one of the first after the change) or `clean` (one from before it, for comparison).

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

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

```json 200
{
  "hasMore": false,
  "records": [
    {
      "sid": "dar_2gH5jK7lM9nP1qR3sT6uV8wX4yZ",
      "driftSid": "drift_2kM4nP6qR8sT1uV3wX5yZ7aB9cD",
      "requestSid": "req_2jK5lM7nP9qR1sT3uV6wX8yZ4aB",
      "role": "onset",
      "observedAt": "2026-10-19T10:02:41.000Z"
    },
    {
      "sid": "dar_2hJ6kL8mN1pQ3rS5tU7vW9xY2zA",
      "driftSid": "drift_2kM4nP6qR8sT1uV3wX5yZ7aB9cD",
      "requestSid": "req_2kL6mN8pQ1rS3tU5vW7xY9zA2bC",
      "role": "clean",
      "observedAt": "2026-10-19T09:58:10.000Z"
    }
  ]
}
```

## Get drift diagnosis

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

Builds a prompt you can paste into an AI coding agent to investigate the change, with the baseline, the requests that show it and the deploys that landed shortly before. The prompt points the agent at the [MCP server](https://www.apitraffic.io/docs/integrations/mcp-server) to fetch the captured requests, rather than including them.

**Plan:** needs **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.

- **driftSid (path, string, required)**:
  The finding's identifier.

### Query parameters

- **environmentSid (query, string)**:
  The environment to look for deploys in. Defaults to the finding's own.

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

### Response

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

- **requests (object[], required)**:
  The requests that show the change, as in [List drift finding requests](#list-drift-finding-requests).

- **deploys (object[], required)**:
  Deploys found before the change, in the same shape as in [Get fix prompt](https://www.apitraffic.io/docs/api-reference/requests#get-fix-prompt).

- **baseline (object | null)**:
  A summary of the baseline.

- **driftSid (string, required)**:
  The finding, with its `bucketSid`, `endpoint`, `method`, `changeType`, `severity`, `classification`, `onsetAt` and `detectedAt`.

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

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

```json 200
{
  "driftSid": "drift_2kM4nP6qR8sT1uV3wX5yZ7aB9cD",
  "bucketSid": "k3m9p2x",
  "endpoint": "/v1/orders/{order_id}",
  "method": "GET",
  "changeType": "breaking_response",
  "severity": "high",
  "classification": "unknown",
  "onsetAt": "2026-10-19T10:02:41.000Z",
  "detectedAt": "2026-10-19T11:15:00.000Z",
  "baseline": {},
  "requests": [
    {
      "sid": "dar_2gH5jK7lM9nP1qR3sT6uV8wX4yZ",
      "driftSid": "drift_2kM4nP6qR8sT1uV3wX5yZ7aB9cD",
      "requestSid": "req_2jK5lM7nP9qR1sT3uV6wX8yZ4aB",
      "role": "onset",
      "observedAt": "2026-10-19T10:02:41.000Z"
    }
  ],
  "deploys": [],
  "prompt": "The response of GET /v1/orders/{order_id} changed at 2026-10-19T10:02:41Z ..."
}
```

## List drift baselines

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

Returns the learned baselines: what each endpoint and method normally looks like.

### Path parameters

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

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

### Query parameters

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

- **status (query, string)**:
  `learning` (still collecting samples), `active` (findings are raised against it) or `superseded` (replaced by a newer version).

- **endpoint (query, string)**:
  Only this endpoint.

- **method (query, string)**:
  Only this method.

- **limit (query, integer, default 250)**:
  Baselines to return, 1 to 1000.

### Response

- **hasMore (boolean, required)**:
  Whether more baselines match.

- **records (object[], required)**:
  One entry per baseline: `sid`, `accountSid`, `bucketSid`, `environmentSid`, `endpoint`, `method`, `version`, `status`, `schema` (the request and response shape), `behavior`, `dependencies`, `sampleCount`, `firstSeenAt` and `lastSeenAt`.

```bash cURL
curl -G https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/buckets/k3m9p2x/driftBaselines \
  -H "Authorization: Bearer $APITRAFFIC_TOKEN" \
  --data-urlencode 'status=active'
```

```js Node.js
const accountSid = 'acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa';
const response = await fetch(
  `https://api.apitraffic.io/v1/accounts/${accountSid}/buckets/k3m9p2x/driftBaselines?status=active`,
  { headers: { Authorization: `Bearer ${process.env.APITRAFFIC_TOKEN}` } },
);
const { records } = await response.json();
```

```json 200
{
  "hasMore": false,
  "records": [
    {
      "sid": "aeb_2pQ4rS6tU8vW1xY3zA5bC7dE9fG",
      "accountSid": "acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa",
      "bucketSid": "k3m9p2x",
      "environmentSid": "prd7k2",
      "endpoint": "/v1/orders/{order_id}",
      "method": "GET",
      "version": 3,
      "status": "active",
      "schema": {},
      "behavior": {},
      "dependencies": {},
      "sampleCount": 1840,
      "firstSeenAt": "2026-09-30T08:00:00.000Z",
      "lastSeenAt": "2026-10-19T09:58:10.000Z"
    }
  ]
}
```

## Get drift health

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

Explains whether drift detection is running for a bucket and why the finding list looks the way it does: turned off, not yet scanned, failing, no traffic, still learning, watching or drifting.

### Path parameters

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

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

### Query parameters

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

### Response

- **state (string, required)**:
  `disabled`, `never_scanned`, `failing`, `no_traffic`, `learning`, `watching` or `drifting`.

- **summary (string, required)**:
  A one-line explanation of `state`, with more in `detail`.

- **lastRunAt (string | null)**:
  When the last scan ran, and `nextRunAt` when the next one is due. `scanIntervalMs` is the time between scans.

- **lastRun (object | null)**:
  The last [scan run](#list-drift-scan-runs), and `lastSuccessfulRun` the last one that succeeded.

- **baselines (object, required)**:
  Baseline counts: `total`, `active` and `learning`.

- **openAlertCount (number, required)**:
  Open findings.

- **failedScopes (number, required)**:
  Scan scopes (bucket and environment) whose last scan failed.

- **totals (object, required)**:
  Totals across recent runs.

- **recentRuns (object[], required)**:
  Recent scan runs, newest first.

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

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

```json 200
{
  "state": "drifting",
  "summary": "1 open finding on 15 watched endpoints.",
  "detail": null,
  "lastRunAt": "2026-10-20T11:15:00.000Z",
  "nextRunAt": "2026-10-20T12:15:00.000Z",
  "scanIntervalMs": 3600000,
  "lastRun": null,
  "lastSuccessfulRun": null,
  "totals": {},
  "baselines": { "total": 15, "active": 14, "learning": 1 },
  "openAlertCount": 1,
  "failedScopes": 0,
  "recentRuns": []
}
```

The example leaves out the run details; see [List drift scan runs](#list-drift-scan-runs) for their fields.

## List drift scan runs

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

Returns recent drift scans, newest first, with what each one looked at.

### Path parameters

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

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

### Query parameters

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

- **status (query, string)**:
  `ok`, `no_traffic` or `failed`.

- **limit (query, integer, default 50)**:
  Runs to return, 1 to 200.

### Response

- **hasMore (boolean, required)**:
  Whether more runs exist.

- **records (object[], required)**:
  One entry per run.

**run**

- **sid (string)**: Run identifier.

- **environmentSid (string | null)**: The environment scanned.

- **status (string)**: `ok`, `no_traffic` or `failed`; `errorMessage` says why it failed.

- **windowFrom (string | null)**: Start of the traffic examined, and `windowTo` its end.

- **endpointsDiscovered (number)**: Endpoints found in the window.

- **endpointsProcessed (number)**: Endpoints sampled.

- **samplesCollected (number)**: Requests sampled.

- **endpointsDiffed (number)**: Endpoints compared against an established baseline.

- **baselinesWritten (number)**: Baselines created or updated. `baselinesActive` and `baselinesLearning` count them by status.

- **findingsWritten (number)**: Findings raised.

- **startedAt (string | null)**: When the run started, `finishedAt` when it ended, and `durationMs` how long it took.

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

```js Node.js
const accountSid = 'acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa';
const response = await fetch(
  `https://api.apitraffic.io/v1/accounts/${accountSid}/buckets/k3m9p2x/driftScanRuns?limit=5`,
  { headers: { Authorization: `Bearer ${process.env.APITRAFFIC_TOKEN}` } },
);
const { records } = await response.json();
const failed = records.filter((run) => run.status === 'failed');
```

```json 200
{
  "hasMore": true,
  "records": [
    {
      "sid": "dscan_2mN5pQ7rS9tU1vW3xY6zA8bC4dE",
      "accountSid": "acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa",
      "bucketSid": "k3m9p2x",
      "environmentSid": "prd7k2",
      "status": "ok",
      "errorMessage": null,
      "windowFrom": "2026-10-20T10:15:00.000Z",
      "windowTo": "2026-10-20T11:15:00.000Z",
      "endpointsDiscovered": 15,
      "endpointsProcessed": 15,
      "samplesCollected": 412,
      "endpointsDiffed": 14,
      "baselinesWritten": 2,
      "baselinesActive": 14,
      "baselinesLearning": 1,
      "findingsWritten": 0,
      "startedAt": "2026-10-20T11:15:00.000Z",
      "finishedAt": "2026-10-20T11:15:09.000Z",
      "durationMs": 9120
    }
  ]
}
```

## Errors

| Status | Code | Meaning |
| --- | --- | --- |
| `400` | `1000` | A parameter is invalid, for example a `driftSid` in the wrong format or an unknown `status`. |
| `403` | `2221` | The plan does not include AI diagnoses (diagnosis only). |
| `403` | `2509` | Changing a finding on the read-only sample bucket. |
| `404` | `4000` | No finding with that sid in this bucket. |
| `429` | `2222` | The monthly AI diagnoses allowance is used up. |

## Related

- [Drift detection](https://www.apitraffic.io/docs/traffic/drift):
    How drift detection works and how to read a finding.

- [Endpoints API](https://www.apitraffic.io/docs/api-reference/endpoints):
    The endpoints drift watches.
