# Sensitive Data API

> List the fields in your API traffic that carry sensitive data, read the data map, decide on fields and change the Sensitive data settings.

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

Sensitive data discovery finds the fields in your API traffic that carry sensitive data types, and says whether each value reaches ApiTraffic redacted. See [Find sensitive data in your API traffic](https://www.apitraffic.io/docs/sensitive-data) for how it works in the app.

Only where each field is and what type of data it holds are stored. No route here ever returns a value.

**Availability:** on for every account. While compliance is switched off for an account, every route here answers `404` with `COMPLIANCE_NOT_ENABLED`. **Plan:** **Sensitive data discovery** (`sensitiveDataDiscovery`); the data map also needs **Sensitive data map** (`sensitiveDataMap`). **Permissions:** any member, or an API token, reads fields, the map and the settings. Accepting a field and marking it a false positive are for owners and admins, signed in: a decision is recorded with the person who made it, so an API token or OAuth connection cannot make one. Removing a decision and changing the settings are for owners and admins, or an `administrator` API token. A token with access scopes needs `security:read` to read and `security:write` for the rest.

## The field object

A field is one location (a header, a query parameter or a body path) of one endpoint, in one bucket and environment, for one data type.

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

- **bucketSid (string, required)**: The bucket, and `environmentSid` the environment.

- **method (string | null)**: The endpoint's method, and `endpoint` its route, with ids replaced by `{id}`.

- **direction (string, required)**: `inbound` (served by your app) or `outbound` (sent by your app to another API).

- **destinationHost (string | null)**: Outbound only: the host it was sent to.

- **location (string, required)**: `request.header`, `request.query`, `request.body`, `response.header` or `response.body`.

- **path (string, required)**: A JSON path (`items[].card.number`), a header or a query parameter name; empty for a whole text body.

- **dataType (string, required)**: The data type (`card_number`, `aws_access_key`, `ssn`), with `label` and `family` (`payment`, `secret`, `government_id`, `health`, `student`, `personal`).

- **confidence (string, required)**: `validated` (a checksum or strict format), `pattern` (the value matched), `context` (the field's name and value agree, or a field beside it confirms it) or `key` (only the name suggests it: shown as possible).

- **indicator (boolean, required)**: Health and student data: an indicator, never certain.

- **counted (boolean, required)**: Whether it counts for the compliance check and the alert.

- **protection (string, required)**: `none` (not redacted), `server` (redacted before storage), `api` (redacted in your API by an SDK rule), `omitted` (not stored) or `stripped` (a credential header ApiTraffic removes).

- **unprotectedShare (number, required)**: The share of the last 7 days' samples that were not redacted, from 0 to 1.

- **covered (boolean, required)**: A body omission rule covers where it is, so it is not stored from now on.

- **status (string, required)**: `open` (not redacted), `protected`, `accepted`, `false_positive` or `stale` (not seen for 30 days). `statusBy`, `statusAt`, `statusNote` and `acceptedUntil` describe a decision.

- **firstSeen (string | null)**: First seen, `lastSeen` last seen, and `lastUnprotectedAt` when it was last seen not redacted.

## Data types

`GET https://api.apitraffic.io/v1/accounts/{accountSid}/sensitive-data/types`

The types discovery can find: `families` and `types`, each with `type`, `label`, `family` and `indicator`.

## List fields

`GET https://api.apitraffic.io/v1/accounts/{accountSid}/sensitive-data/fields`

Unprotected payment, secret, health and government id fields first. Returns `fields`, `total`, `limit` and `offset`.

### Query parameters

- **bucketSid (query, string)**: Only this bucket.

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

- **family (query, string)**: Families, separated by commas.

- **dataType (query, string)**: Data types, separated by commas.

- **protection (query, string)**: Protection states, separated by commas.

- **confidence (query, string)**: Confidences, separated by commas.

- **status (query, string)**: Statuses, separated by commas. Without it, stale fields are left out.

- **direction (query, string)**: `inbound` or `outbound`.

- **destinationHost (query, string)**: Only fields sent to this host.

- **endpoint (query, string)**: Method and endpoint, as `POST /payments`.

- **counted (query, boolean)**: Only fields that count (`true`) or only possible ones (`false`).

- **limit (query, integer, default 50)**: 1 to 500.

- **offset (query, integer, default 0)**: Fields to skip.

## Get a field

`GET https://api.apitraffic.io/v1/accounts/{accountSid}/sensitive-data/fields/{fieldSid}`

The field with `days`, its samples per day by protection over the 7 days its protection is judged on, and `decision` (`decision`, `note`, `decidedBy`, `decidedAt`, `acceptedUntil`) or `null`. Takes `bucketSid`: a field in another bucket is not found.

## Data map

`GET https://api.apitraffic.io/v1/accounts/{accountSid}/sensitive-data/map`

Takes `bucketSid` and `environmentSid`. Stale fields and false positives are left out.

- **totals (object, required)**: `fields`, `unprotected`, `types`, `endpoints` and `destinations`.

- **types (object[], required)**: Each type found: `dataType`, `label`, `family`, and how many `fields` carry it, how many are `counted` and how many `unprotected`.

- **endpoints (object[], required)**: Each endpoint: `bucketSid`, `environmentSid`, `direction`, `method`, `endpoint`, the types in its `request` and `response`, and `unprotected`.

- **destinations (object[], required)**: Each outbound host: the `types` sent to it, `credentialsSent` (secret types sent in credential headers, which never count), `fields` and `unprotected`.

- **truncated (boolean, required)**: More than 1,000 endpoints or destinations: the busiest unprotected ones are listed, and the totals count all.

## Decisions

`POST https://api.apitraffic.io/v1/accounts/{accountSid}/sensitive-data/fields/{fieldSid}/accept`

`POST https://api.apitraffic.io/v1/accounts/{accountSid}/sensitive-data/fields/{fieldSid}/false-positive`

`DELETE https://api.apitraffic.io/v1/accounts/{accountSid}/sensitive-data/fields/{fieldSid}/decision`

| Action | Body |
| --- | --- |
| Accept | `note` (why, required), `acceptedUntil` (required, at most a year away) |
| False positive | `note` (why it is not sensitive data, required) |
| Remove the decision | none |

Each returns the field as [Get a field](#get-a-field) does. A decision takes the field out of the compliance check and resolves its alert. An acceptance ends on its date, and a value later found in a false positive field that passes a checksum takes the decision away; the field then takes the status its protection gives. Each decision is recorded in the account history.

## Settings

`GET https://api.apitraffic.io/v1/accounts/{accountSid}/sensitive-data/settings`

`PATCH https://api.apitraffic.io/v1/accounts/{accountSid}/sensitive-data/settings`

Returns `account` (`discoveryEnabled`, `treatPossibleAsSensitive`), `bucket` when `bucketSid` is given (`discoveryEnabled`, `null` to follow the account, and `countTestCards`), and `effective`: the settings in force. A `null` setting follows the default: discovery on, test cards and possible detections not counted.

A change takes `bucketSid` (to change a bucket's settings; without it, the account's) and any of:

- **discoveryEnabled (body, boolean | null)**: Discover sensitive data. On a bucket, `null` follows the account.

- **countTestCards (body, boolean | null)**: A bucket only: count published test card numbers as card numbers.

- **treatPossibleAsSensitive (body, boolean | null)**: The account only: count possible health and student data (field name only) as sensitive.

## Errors

| Status | Code | When |
| --- | --- | --- |
| 400 | `SENSITIVE_FIELD_DECISION_INVALID` | The decision cannot be recorded as asked: an end date in the past or more than a year away, or the caller is a credential (an API token or OAuth connection), not a person. |
| 400 | `SENSITIVE_DATA_SETTINGS_INVALID` | `countTestCards` without a bucket, `treatPossibleAsSensitive` with one, or a bucket not in the account. |
| 404 | `COMPLIANCE_NOT_ENABLED` | Compliance is switched off for the account. |
| 404 | `SENSITIVE_FIELD_NOT_FOUND` | The field was not found. |
