# Buckets API

> List, create, configure and delete buckets, and download the settings ApiTraffic SDKs load: redactions, exclusions, firewall, APM and host telemetry.

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

A bucket holds the traffic of one application or API. Its settings decide what is indexed for search, how endpoints are learned, what APM spans may capture and whether servers report host telemetry. See [Buckets](https://www.apitraffic.io/docs/account/buckets) for doing this in the app.

The last four operations on this page return the configuration an SDK downloads when it starts. They are what the SDK calls; you only need them to inspect that configuration or to pin it as [offline definitions](https://www.apitraffic.io/docs/reference/offline-definitions).

**Permissions:** any member, or a `user` or `administrator` API token, can list, create and update buckets. Deleting a bucket, and turning on SQL parameter or Redis key capture, need an owner or admin, or an `administrator` API token. The SDK configuration operations also accept `ingest` tokens.

## The bucket object

- **sid (string, required)**:
  The bucket's identifier (7 lowercase letters and digits).

- **accountSid (string, required)**:
  The account the bucket belongs to.

- **name (string, required)**:
  The bucket's name.

- **verifySslCerts (boolean, required)**:
  Whether TLS certificates are verified as valid and trusted. Default `true`.

- **searchBodyLogging (string, required)**:
  Which bodies may be indexed for search: `none` (default), `request`, `response` or `both`.

- **endpointLearningEnabled (boolean, required)**:
  Whether path segments that vary may be learned as parameters, for example `/v1/orders/{order_id}`. Default `true`.

- **endpointLearningMinValues (integer, required)**:
  How many distinct values a segment between two fixed parts of a path must take before it is treated as a parameter. Default `2`. Segments at the end of a path, or right after another parameter, always need at least 25.

- **driftDetectionEnabled (boolean, required)**:
  Whether [API drift](https://www.apitraffic.io/docs/traffic/drift) scans run for this bucket. Default `false`.

- **apmCaptureStatementParams (boolean, required)**:
  Whether APM spans may include full SQL statements with their bind parameters. Off, only the normalized statement is captured. Default `false`.

- **apmCaptureRedisKeys (boolean, required)**:
  Whether APM spans may include concrete Redis keys instead of masked key shapes. Default `false`.

- **apmCaptureExpiresAt (string | null, required)**:
  When the two switches above turn themselves off (ISO 8601). `null` means they stay as set.

- **apmCaptureCallSite (boolean, required)**:
  Whether APM spans record the file, line and function in your code that started the operation. Default `true`.

- **apmCaptureStackDepth (integer, required)**:
  How many application frames are kept per span, innermost first, from 1 (the call site alone) to 50. Default `10`.

- **hostTelemetryEnabled (boolean)**:
  Whether connected servers report CPU, memory, event-loop and garbage-collection health. Default `false`.

- **hostSampleIntervalMs (integer | null)**:
  The reporting interval you asked for, in milliseconds. It is clamped into the range your plan allows. `null` uses the plan's default.

- **hostTelemetryExpensive (boolean)**:
  Whether servers also report disk, network and per-core CPU. These run at most once every 60 seconds. Default `false`.

- **hostTelemetryCaptureIdentity (boolean)**:
  Whether host and pod names are reported next to the hashed machine id. Default `true`.

- **appIsConnected (boolean, required)**:
  Whether an SDK has connected to the bucket.

- **isSample (boolean)**:
  `true` for the shared, read-only [sample bucket](https://www.apitraffic.io/docs/sample-data); `false` for the account's own buckets.

- **createdAt (string, required)**:
  When the bucket was created (ISO 8601).

## List buckets

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

Returns every bucket in the account. When sample data is turned on, a signed-in person also gets the sample bucket last, with `isSample: true`. API tokens and OAuth applications never see it, so a script that loops over buckets only meets the account's own.

### Path parameters

- **accountSid (path, string, required)**:
  The account identifier (`acc_` followed by 27 letters and digits).

### Response

- **hasMore (boolean, required)**:
  Always `false`: every bucket is returned in one response.

- **records (object[], required)**:
  The buckets, as [bucket objects](#the-bucket-object).

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

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

```json 200
{
  "hasMore": false,
  "records": [
    {
      "sid": "k3m9p2x",
      "accountSid": "acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa",
      "name": "Acme Store API",
      "verifySslCerts": true,
      "searchBodyLogging": "both",
      "endpointLearningEnabled": true,
      "endpointLearningMinValues": 2,
      "apmCaptureStatementParams": false,
      "apmCaptureRedisKeys": false,
      "apmCaptureCallSite": true,
      "apmCaptureStackDepth": 10,
      "driftDetectionEnabled": true,
      "apmCaptureExpiresAt": null,
      "hostTelemetryEnabled": true,
      "hostSampleIntervalMs": 120000,
      "hostTelemetryExpensive": false,
      "hostTelemetryCaptureIdentity": true,
      "appIsConnected": true,
      "createdAt": "2026-03-02T15:35:00.000Z",
      "isSample": false
    }
  ]
}
```

## Get bucket

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

Returns one bucket.

### Path parameters

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

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

### Response

A [bucket object](#the-bucket-object).

```bash cURL
curl https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/buckets/k3m9p2x \
  -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`, {
  headers: { Authorization: `Bearer ${process.env.APITRAFFIC_TOKEN}` },
});
const bucket = await response.json();
```

```json 200
{
  "sid": "k3m9p2x",
  "accountSid": "acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa",
  "name": "Acme Store API",
  "verifySslCerts": true,
  "searchBodyLogging": "both",
  "endpointLearningEnabled": true,
  "endpointLearningMinValues": 2,
  "apmCaptureStatementParams": false,
  "apmCaptureRedisKeys": false,
  "apmCaptureCallSite": true,
  "apmCaptureStackDepth": 10,
  "driftDetectionEnabled": true,
  "apmCaptureExpiresAt": null,
  "hostTelemetryEnabled": true,
  "hostSampleIntervalMs": 120000,
  "hostTelemetryExpensive": false,
  "hostTelemetryCaptureIdentity": true,
  "appIsConnected": true,
  "createdAt": "2026-03-02T15:35:00.000Z"
}
```

## Create bucket

`POST https://api.apitraffic.io/v1/accounts/{accountSid}/buckets`

Creates a bucket with default settings. Change them afterwards with [Update bucket](#update-bucket).

**Limit:** the number of buckets depends on the plan; past it, the API answers `409` with code `2213` and `data` carries `allowance` and `currentCount`.

### Path parameters

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

### Body parameters

- **name (body, string, required)**:
  The bucket's name.

### Response

The new [bucket object](#the-bucket-object).

```bash cURL
curl -X POST https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/buckets \
  -H "Authorization: Bearer $APITRAFFIC_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Acme Store Admin API" }'
```

```js Node.js
const accountSid = 'acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa';
const response = await fetch(`https://api.apitraffic.io/v1/accounts/${accountSid}/buckets`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.APITRAFFIC_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ name: 'Acme Store Admin API' }),
});
const bucket = await response.json();
```

```json 200
{
  "sid": "w7d4q8n",
  "accountSid": "acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa",
  "name": "Acme Store Admin API",
  "verifySslCerts": true,
  "searchBodyLogging": "none",
  "endpointLearningEnabled": true,
  "endpointLearningMinValues": 2,
  "apmCaptureStatementParams": false,
  "apmCaptureRedisKeys": false,
  "apmCaptureCallSite": true,
  "apmCaptureStackDepth": 10,
  "driftDetectionEnabled": false,
  "apmCaptureExpiresAt": null,
  "hostTelemetryEnabled": false,
  "hostSampleIntervalMs": null,
  "hostTelemetryExpensive": false,
  "hostTelemetryCaptureIdentity": true,
  "appIsConnected": false,
  "createdAt": "2026-10-20T09:00:00.000Z"
}
```

## Update bucket

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

Changes a bucket's settings. `name` and `verifySslCerts` are always required; every other field is optional and left as it is when omitted. Connected SDKs pick up APM and host telemetry changes without a restart.

**Plan:** turning `driftDetectionEnabled` on needs a plan that includes **API drift detection**; turning it off always works.

**Permissions:** turning `apmCaptureStatementParams` or `apmCaptureRedisKeys` on (from off to `true`) needs an owner or admin, or an `administrator` API token, because both put personal data into spans. Turning them off, or sending the value the bucket already has, needs no extra role. The example below turns one on, so it needs an `administrator` token.

> **Note:** `searchBodyLogging` is set only through this operation. It decides which bodies (`none`, `request`, `response` or `both`) may be indexed, so that [search](https://www.apitraffic.io/docs/traffic/search) conditions on request and response bodies can match them. Searching bodies also needs a plan that includes body search.

### Path parameters

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

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

### Body parameters

- **name (body, string, required)**:
  The bucket's name.

- **verifySslCerts (body, boolean, required)**:
  Whether TLS certificates must be valid and trusted.

- **searchBodyLogging (body, string)**:
  `none`, `request`, `response` or `both`.

- **endpointLearningEnabled (body, boolean)**:
  Whether varying path segments may be learned as parameters.

- **endpointLearningMinValues (body, integer)**:
  Distinct values before a segment becomes a parameter, 2 to 100.

- **driftDetectionEnabled (body, boolean)**:
  Whether drift scans run for this bucket.

- **apmCaptureStatementParams (body, boolean)**:
  Capture full SQL statements with bind parameters. Turning it on needs owner, admin or `administrator` access.

- **apmCaptureRedisKeys (body, boolean)**:
  Capture concrete Redis keys. Turning it on needs owner, admin or `administrator` access.

- **apmCaptureExpiresAt (body, string | null)**:
  When the two switches above turn off (ISO 8601). `null` keeps them on until you turn them off. See [APM capture settings](https://www.apitraffic.io/docs/apm/capture-settings).

- **apmCaptureCallSite (body, boolean)**:
  Record where in your code each span started. Off, no location, function or stack is captured.

- **apmCaptureStackDepth (body, integer)**:
  Application frames kept per span, 1 to 50.

- **hostTelemetryEnabled (body, boolean)**:
  Whether servers report host health.

- **hostSampleIntervalMs (body, integer | null)**:
  Reporting interval in milliseconds, 1000 to 600000. It is clamped into the range your plan allows rather than refused. `null` uses the plan default.

- **hostTelemetryExpensive (body, boolean)**:
  Also report disk, network and per-core CPU (at most every 60 seconds).

- **hostTelemetryCaptureIdentity (body, boolean)**:
  Report host and pod names. Off, only the hashed machine id is reported.

### Response

The updated [bucket object](#the-bucket-object).

```bash cURL
curl -X PUT https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/buckets/k3m9p2x \
  -H "Authorization: Bearer $APITRAFFIC_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme Store API",
    "verifySslCerts": true,
    "apmCaptureStatementParams": true,
    "apmCaptureExpiresAt": "2026-10-20T13:00:00.000Z"
  }'
```

```js Node.js
const accountSid = 'acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa';
const response = await fetch(`https://api.apitraffic.io/v1/accounts/${accountSid}/buckets/k3m9p2x`, {
  method: 'PUT',
  headers: {
    Authorization: `Bearer ${process.env.APITRAFFIC_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    name: 'Acme Store API',
    verifySslCerts: true,
    apmCaptureStatementParams: true,
    // Turn the switch off again automatically in four hours.
    apmCaptureExpiresAt: new Date(Date.now() + 4 * 3600 * 1000).toISOString(),
  }),
});
const bucket = await response.json();
```

```json 200
{
  "sid": "k3m9p2x",
  "accountSid": "acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa",
  "name": "Acme Store API",
  "verifySslCerts": true,
  "searchBodyLogging": "both",
  "endpointLearningEnabled": true,
  "endpointLearningMinValues": 2,
  "apmCaptureStatementParams": true,
  "apmCaptureRedisKeys": false,
  "apmCaptureCallSite": true,
  "apmCaptureStackDepth": 10,
  "driftDetectionEnabled": true,
  "apmCaptureExpiresAt": "2026-10-20T13:00:00.000Z",
  "hostTelemetryEnabled": true,
  "hostSampleIntervalMs": 120000,
  "hostTelemetryExpensive": false,
  "hostTelemetryCaptureIdentity": true,
  "appIsConnected": true,
  "createdAt": "2026-03-02T15:35:00.000Z"
}
```

## Delete bucket

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

Deletes a bucket and the requests captured in it. This cannot be undone.

**Permissions:** owner or admin, or an `administrator` API token.

### Path parameters

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

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

### Response

- **sid (string, required)**:
  The deleted bucket's identifier.

- **deleted (boolean, required)**:
  `true`.

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

```js Node.js
const accountSid = 'acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa';
await fetch(`https://api.apitraffic.io/v1/accounts/${accountSid}/buckets/w7d4q8n`, {
  method: 'DELETE',
  headers: { Authorization: `Bearer ${process.env.APITRAFFIC_TOKEN}` },
});
```

```json 200
{
  "sid": "w7d4q8n",
  "deleted": true
}
```

## Get SDK settings

`GET https://api.apitraffic.io/v1/buckets/{bucketSid}/sdk`

Returns the configuration an SDK applies for a bucket: redaction and exclusion rules, the firewall policy, APM capture switches and host telemetry settings, plus a short-lived credential for live configuration updates. ApiTraffic SDKs call this when they start; you rarely need to.

Authenticate with the SDK's own token. The account and environment come from the token, which is why the path names only the bucket.

**Permissions:** any API token of the account, including `ingest`.

### Path parameters

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

### Query parameters

- **redactAt (query, string, required)**:
  Which redaction rules to return: `client` (applied in your application) or `server` (applied by ApiTraffic).

- **clientId (query, string, required)**:
  An identifier for the calling process. The live-update credential is issued for it.

### Response

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

- **environmentSid (string, required)**:
  The token's environment.

- **redactions (object[], required)**:
  The redaction rules that apply to this bucket and environment at `redactAt`.

- **exclusions (object[], required)**:
  The exclusion rules that apply to this bucket and environment.

- **waf (object)**:
  The firewall policy: `configVersion`, `mode`, `engineTier` and `policy`. Absent when no policy applies, or the plan does not include the **Web application firewall**.

- **apm (object, required)**:
  The effective [APM capture switches](https://www.apitraffic.io/docs/apm/capture-settings): `captureStatementParams`, `captureRedisKeys`, `captureCallSite`, `captureStackDepth` and `expiresAt`. Once `apmCaptureExpiresAt` has passed, `captureStatementParams` and `captureRedisKeys` are reported as `false` and `expiresAt` as `null`, so servers stop capturing even if nobody returns to the dashboard.

- **hostTelemetry (object, required)**:
  `enabled`, `intervalMs` (already clamped to the plan), `floorMs`, `ceilingMs`, `captureExpensive` and `captureIdentity`.

- **realtime (object)**:
  The live-update channel and its short-lived credential. Never stored in offline definitions.

- **ingest (object)**:
  How the SDK may send captured traffic.

- **configHash (string, required)**:
  `sha256:` hash of the configuration. Servers report it back, so the app can tell whether pinned offline definitions are stale.

- **mirrorUrl (string)**:
  Where a copy of this configuration is mirrored, when a mirror is set up.

```bash cURL
curl "https://api.apitraffic.io/v1/buckets/k3m9p2x/sdk?redactAt=client&clientId=acme-api-1" \
  -H "Authorization: Bearer $APITRAFFIC_INGEST_TOKEN"
```

```js Node.js
const params = new URLSearchParams({ redactAt: 'client', clientId: 'acme-api-1' });
const response = await fetch(`https://api.apitraffic.io/v1/buckets/k3m9p2x/sdk?${params}`, {
  headers: { Authorization: `Bearer ${process.env.APITRAFFIC_INGEST_TOKEN}` },
});
const settings = await response.json();
console.log(settings.configHash, settings.apm);
```

```json 200
{
  "accountSid": "acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa",
  "environmentSid": "prd7k2",
  "redactions": [],
  "exclusions": [],
  "apm": {
    "captureStatementParams": false,
    "captureRedisKeys": false,
    "captureCallSite": true,
    "captureStackDepth": 10,
    "expiresAt": null
  },
  "hostTelemetry": {
    "enabled": true,
    "intervalMs": 120000,
    "floorMs": 15000,
    "ceilingMs": 600000,
    "captureExpensive": false,
    "captureIdentity": true
  },
  "waf": {
    "configVersion": 7,
    "mode": "block",
    "engineTier": "native",
    "policy": {}
  },
  "configHash": "sha256:9f2b1c4a7e08d3f5b6c1a2d4e8f09b3c5d7e1f2a4b6c8d0e2f4a6b8c0d2e4f6a"
}
```

The example leaves out `realtime` and `ingest`, and shortens the rule lists and the policy.

## Download offline definitions

`GET https://api.apitraffic.io/v1/buckets/{bucketSid}/sdk/snapshot`

Returns the same configuration as [Get SDK settings](#get-sdk-settings), without the live-update credential, wrapped with a content hash. This is the file an SDK falls back to when it starts and cannot reach ApiTraffic: commit it to `.apitraffic/definitions/sdk.json`. See [Offline definitions](https://www.apitraffic.io/docs/reference/offline-definitions), and the [CLI](https://www.apitraffic.io/docs/reference/cli), which wraps this operation.

Authenticate with the token your SDK already uses, so CI can fetch the file without a new credential.

**Permissions:** any API token of the account, including `ingest`.

### Path parameters

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

### Query parameters

- **redactAt (query, string, default client)**:
  `client` or `server`. An SDK pins `client`.

### Response

- **schemaVersion (integer, required)**:
  The file format version. An SDK refuses a version it does not understand.

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

- **environmentSid (string, required)**:
  The environment the configuration is for.

- **bucketSid (string, required)**:
  The bucket. An SDK refuses a file whose `bucketSid` is not its own.

- **redactAt (string, required)**:
  `client` or `server`.

- **generatedAt (string, required)**:
  When the file was generated (ISO 8601). Not part of the hash, so regenerating an unchanged configuration gives the same `configHash`.

- **configHash (string, required)**:
  `sha256:` hash of `config`.

- **mirrorUrl (string)**:
  Where a copy of the configuration is mirrored, when a mirror is set up.

- **config (object, required)**:
  `redactions` and `exclusions`, plus `apm`, `hostTelemetry` and `waf` when they apply. `apm` has no `expiresAt`.

> **Warning:** The file contains your firewall policy and redaction rules: what you block, and which fields you consider sensitive. Commit it to a private repository only.

```bash cURL
curl "https://api.apitraffic.io/v1/buckets/k3m9p2x/sdk/snapshot?redactAt=client" \
  -H "Authorization: Bearer $APITRAFFIC_INGEST_TOKEN" \
  -o .apitraffic/definitions/sdk.json
```

```js Node.js
import { writeFile } from 'node:fs/promises';

const response = await fetch('https://api.apitraffic.io/v1/buckets/k3m9p2x/sdk/snapshot?redactAt=client', {
  headers: { Authorization: `Bearer ${process.env.APITRAFFIC_INGEST_TOKEN}` },
});
const snapshot = await response.json();
await writeFile('.apitraffic/definitions/sdk.json', JSON.stringify(snapshot, null, 2));
```

```json 200
{
  "schemaVersion": 1,
  "accountSid": "acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa",
  "environmentSid": "prd7k2",
  "bucketSid": "k3m9p2x",
  "redactAt": "client",
  "generatedAt": "2026-10-20T09:15:00.000Z",
  "configHash": "sha256:9f2b1c4a7e08d3f5b6c1a2d4e8f09b3c5d7e1f2a4b6c8d0e2f4a6b8c0d2e4f6a",
  "config": {
    "redactions": [],
    "exclusions": [],
    "apm": {
      "captureStatementParams": false,
      "captureRedisKeys": false,
      "captureCallSite": true,
      "captureStackDepth": 10
    },
    "hostTelemetry": {
      "enabled": true,
      "intervalMs": 120000,
      "floorMs": 15000,
      "ceilingMs": 600000,
      "captureExpensive": false,
      "captureIdentity": true
    },
    "waf": {
      "configVersion": 7,
      "mode": "block",
      "engineTier": "native",
      "policy": {}
    }
  }
}
```

## Download offline definitions (account session)

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

The same file as [Download offline definitions](#download-offline-definitions), for callers whose token carries no environment, such as a person signed in to the app. This is what the app's download button calls. You name the environment in the query.

**Permissions:** any member, or any API token of the account.

### Path parameters

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

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

### Query parameters

- **environmentSid (query, string, required)**:
  The environment the configuration is for.

- **redactAt (query, string, default client)**:
  `client` or `server`.

### Response

The same envelope as [Download offline definitions](#download-offline-definitions).

```bash cURL
curl "https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/buckets/k3m9p2x/sdk/snapshot?environmentSid=prd7k2" \
  -H "Authorization: Bearer $APITRAFFIC_TOKEN" \
  -o .apitraffic/definitions/sdk.json
```

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

```json 200
{
  "schemaVersion": 1,
  "accountSid": "acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa",
  "environmentSid": "prd7k2",
  "bucketSid": "k3m9p2x",
  "redactAt": "client",
  "generatedAt": "2026-10-20T09:15:00.000Z",
  "configHash": "sha256:9f2b1c4a7e08d3f5b6c1a2d4e8f09b3c5d7e1f2a4b6c8d0e2f4a6b8c0d2e4f6a",
  "config": {
    "redactions": [],
    "exclusions": []
  }
}
```

## Get config hash

`GET https://api.apitraffic.io/v1/accounts/{accountSid}/buckets/{bucketSid}/sdk/config-hash`

The offline definitions envelope without `config`. Use it to check whether a committed file is stale (compare `configHash`) without downloading the whole firewall policy. The app's **Servers** page uses it to badge each server.

**Permissions:** any member, or any API token of the account.

### Path parameters

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

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

### Query parameters

- **environmentSid (query, string, required)**:
  The environment the hash is for.

- **redactAt (query, string, default client)**:
  `client` or `server`.

### Response

`schemaVersion`, `accountSid`, `environmentSid`, `bucketSid`, `redactAt`, `generatedAt`, `configHash` and, when set up, `mirrorUrl`: the fields of [Download offline definitions](#download-offline-definitions) except `config`.

```bash cURL
curl "https://api.apitraffic.io/v1/accounts/acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa/buckets/k3m9p2x/sdk/config-hash?environmentSid=prd7k2" \
  -H "Authorization: Bearer $APITRAFFIC_TOKEN"
```

```js Node.js
import { readFile } from 'node:fs/promises';

const accountSid = 'acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa';
const response = await fetch(
  `https://api.apitraffic.io/v1/accounts/${accountSid}/buckets/k3m9p2x/sdk/config-hash?environmentSid=prd7k2`,
  { headers: { Authorization: `Bearer ${process.env.APITRAFFIC_TOKEN}` } },
);
const { configHash } = await response.json();
const pinned = JSON.parse(await readFile('.apitraffic/definitions/sdk.json', 'utf8'));
if (pinned.configHash !== configHash) console.log('Offline definitions are stale');
```

```json 200
{
  "schemaVersion": 1,
  "accountSid": "acc_2mXq7RbT4kPz9WvN3cHd8LsYfQa",
  "environmentSid": "prd7k2",
  "bucketSid": "k3m9p2x",
  "redactAt": "client",
  "generatedAt": "2026-10-20T09:15:00.000Z",
  "configHash": "sha256:9f2b1c4a7e08d3f5b6c1a2d4e8f09b3c5d7e1f2a4b6c8d0e2f4a6b8c0d2e4f6a"
}
```

## Errors

| Status | Code | Meaning |
| --- | --- | --- |
| `400` | `1000` | A field is missing or invalid, for example `endpointLearningMinValues` outside 2 to 100. |
| `403` | `2010` | Deleting a bucket, or turning on `apmCaptureStatementParams` or `apmCaptureRedisKeys`, without owner, admin or `administrator` access; or an `ingest` token on anything but the SDK operations. |
| `403` | `2221` | Turning on drift detection on a plan without it. |
| `403` | `2509` | Changing or deleting the read-only sample bucket. |
| `404` | `4000` | No bucket with that sid in this account. |
| `409` | `2213` | The plan's bucket limit is reached. |

## Related

- [Buckets](https://www.apitraffic.io/docs/account/buckets):
    Create and configure buckets in the app.

- [Offline definitions](https://www.apitraffic.io/docs/reference/offline-definitions):
    Pin the SDK configuration so servers start safely without ApiTraffic.

- [Requests API](https://www.apitraffic.io/docs/api-reference/requests):
    Search the traffic captured in a bucket.
