
## Authentication

This API uses [basic authentication](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization#basic_authentication), using the API key and secret key for your project. Pass base64-encoded credentials in the request header like `{api-key}:{secret-key}`. `api-key` replaces username, and `secret-key` replaces the password.

Your authorization header should look something like this:

`--header 'Authorization: Basic YWhhbWwsdG9uQGFwaWdlZS5jb206bClwYXNzdzByZAo'`

For more information, go to [Find your API Credentials](/docs/apis/authentication).

The key/secret pair scopes the API call to a single project, so a call from project A's keys can never read or write project B's classifiers.

## Endpoints

| Data residency | Endpoint                                                       |
| -------------- | -------------------------------------------------------------- |
| Default        | `https://amplitude.com/api/2/channel-classifiers`              |
| EU             | `https://analytics.eu.amplitude.com/api/2/channel-classifiers` |

Requests use `https://amplitude.com` (default) or `https://analytics.eu.amplitude.com` (EU). The `https://analytics.amplitude.com` hostname is the Analytics web app (browser UI); use the hosts in this table for REST requests, not `analytics.amplitude.com`.

## List classifiers

Returns every channel classifier in the authenticated project.

`GET https://amplitude.com/api/2/channel-classifiers`

{% code-group %}
```bash cURL
curl --location --request GET 'https://amplitude.com/api/2/channel-classifiers' \
-u '{api-key}:{secret-key}'
```

```bash HTTP
GET /api/2/channel-classifiers HTTP/1.1
Host: amplitude.com
Authorization: Basic {api-key}:{secret-key} #credentials must be base64 encoded
```
{% /code-group %}

### Response

```json
{
  "channelClassifiers": [
    {
      "id": "368",
      "name": "utm_channels",
      "displayName": "UTM Channels",
      "description": "Standard channel attribution",
      "csvText": "Channel,utm_source,utm_medium\nPaid Search,google|bing,cpc|paid\nDirect,ANY,direct",
      "csvDefinition": {
        "csvText": "Channel,utm_source,utm_medium\nPaid Search,google|bing,cpc|paid\nDirect,ANY,direct",
        "operatorsMap": { "utm_source": "IS", "utm_medium": "IS" },
        "columnMetadata": { "utm_source": "event_property", "utm_medium": "event_property" },
        "columnMetadataGroupType": {},
        "anyKeyword": "ANY",
        "separator": "|",
        "propertyMetadata": {},
        "useWaterfallLogic": true
      },
      "lastModified": "2026-05-10T18:09:22.275499"
    }
  ]
}
```

{% callout type="note" heading="Using GET responses with update" %}
Both `GET` endpoints return the full `csvDefinition` object — the same shape `POST` and `PATCH` accept — so you can read a classifier and feed its `csvDefinition` straight back into an update. The top-level `csvText` is also kept for convenience.

Read the `separator` value from the response and pass it back unchanged rather than assuming a specific delimiter. Classifiers created in the Amplitude UI use an internal separator token (for example, `<ampSeparator>`); Amplitude doesn't rewrite it to a common delimiter because real values can contain commas or pipes, which would collide. `separator` may also be `null` when a classifier was saved without a multi-value delimiter — pass `null` back as-is.
{% /callout %}

### Error responses

- `401` - Missing or malformed `Authorization` header.
- `403` - Invalid API key or secret.

## Get a classifier by name

Returns the full definition for a single classifier by its `name`.

`GET https://amplitude.com/api/2/channel-classifiers/{name}`

{% code-group %}
```bash cURL
curl --location --request GET 'https://amplitude.com/api/2/channel-classifiers/utm_channels' \
-u '{api-key}:{secret-key}'
```

```bash HTTP
GET /api/2/channel-classifiers/utm_channels HTTP/1.1
Host: amplitude.com
Authorization: Basic {api-key}:{secret-key} #credentials must be base64 encoded
```
{% /code-group %}

### Path parameters

| Parameter | Description                                                                                                              |
| --------- | ------------------------------------------------------------------------------------------------------------------------ |
| `name`    | Required. String. The classifier's `derivedPropertyName`, exactly as returned by the [list endpoint](#list-classifiers). Classifiers created in the Amplitude UI have a UUID identifier (for example, `1394d15a-d7fa-4d6f-81a7-56dd27be6f4c`). |

### Response

```json
{
  "id": "368",
  "name": "utm_channels",
  "displayName": "UTM Channels",
  "description": "Standard channel attribution",
  "csvText": "Channel,utm_source,utm_medium\nPaid Search,google|bing,cpc|paid\nDirect,ANY,direct",
  "csvDefinition": {
    "csvText": "Channel,utm_source,utm_medium\nPaid Search,google|bing,cpc|paid\nDirect,ANY,direct",
    "operatorsMap": { "utm_source": "IS", "utm_medium": "IS" },
    "columnMetadata": { "utm_source": "event_property", "utm_medium": "event_property" },
    "columnMetadataGroupType": {},
    "anyKeyword": "ANY",
    "separator": "|",
    "propertyMetadata": {},
    "useWaterfallLogic": true
  },
  "lastModified": "2026-05-10T18:09:22.275499"
}
```

### Error responses

- `401` - Missing or malformed `Authorization` header.
- `403` - Invalid API key or secret.
- `404` - Classifier with that name not found in this project.

## Create a classifier

Creates a new classifier under the `name` you provide. Fails with `409` if a classifier with that name already exists in the project.

`POST https://amplitude.com/api/2/channel-classifiers/{name}`

{% code-group %}
```bash cURL
curl --location --request POST 'https://amplitude.com/api/2/channel-classifiers/utm_channels' \
--header 'Authorization: Basic {api-key}:{secret-key}' \
--header 'Content-Type: application/json' \
--data-raw '{
  "displayName": "UTM Channels",
  "description": "Standard paid/organic/social/email/direct/referral",
  "csvDefinition": {
    "csvText": "Channel,utm_source,utm_medium\nPaid Search,google|bing,cpc|paid\nOrganic Search,google|bing,organic\nEmail,ANY,email\nDirect,ANY,direct",
    "operatorsMap": {"utm_source": "IS", "utm_medium": "IS"},
    "columnMetadata": {"utm_source": "event_property", "utm_medium": "event_property"},
    "anyKeyword": "ANY",
    "separator": "|",
    "propertyMetadata": {},
    "useWaterfallLogic": true
  }
}'
```

```bash HTTP
POST /api/2/channel-classifiers/utm_channels HTTP/1.1
Host: amplitude.com
Authorization: Basic {api-key}:{secret-key} #credentials must be base64 encoded
Content-Type: application/json

{
  "displayName": "UTM Channels",
  "description": "Standard paid/organic/social/email/direct/referral",
  "csvDefinition": {
    "csvText": "Channel,utm_source,utm_medium\nPaid Search,google|bing,cpc|paid\nOrganic Search,google|bing,organic\nEmail,ANY,email\nDirect,ANY,direct",
    "operatorsMap": {"utm_source": "IS", "utm_medium": "IS"},
    "columnMetadata": {"utm_source": "event_property", "utm_medium": "event_property"},
    "anyKeyword": "ANY",
    "separator": "|",
    "propertyMetadata": {},
    "useWaterfallLogic": true
  }
}
```
{% /code-group %}

### Path parameters

| Parameter | Description                                                                                                                                            |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `name`    | Required. String. The classifier's stable identifier. Use this in the URL when you call `GET` or `PATCH` later. Letters, digits, underscores, and hyphens only. |

### Body parameters

| Parameter       | Description                                                                                       |
| --------------- | ------------------------------------------------------------------------------------------------- |
| `displayName`   | Optional. String, max 1000 chars. Human-readable label that appears in the UI.                    |
| `description`   | Optional. String, max 1000 chars. Free-form description.                                          |
| `csvDefinition` | Required. Object. The classifier definition. Go to [csvDefinition fields](#csvdefinition-fields). |

### Response

```json
{
  "status": "created",
  "name": "utm_channels"
}
```

### Error responses

- `400` - Body missing `csvDefinition`, missing `csvDefinition.csvText`, or `displayName`/`description` longer than 1000 chars.
- `401` - Missing or malformed `Authorization` header.
- `403` - Invalid API key or secret.
- `409` - Classifier with that name already exists in this project.
- `413` - `csvDefinition.csvText` is larger than 1 MB.

## Update a classifier

Replaces the definition of an existing classifier with the full `csvDefinition` from the request body. Amplitude doesn't support partial CSV updates, and updates `displayName` and `description` only when you supply them.

`PATCH https://amplitude.com/api/2/channel-classifiers/{name}`

{% code-group %}
```bash cURL
curl --location --request PATCH 'https://amplitude.com/api/2/channel-classifiers/utm_channels' \
--header 'Authorization: Basic {api-key}:{secret-key}' \
--header 'Content-Type: application/json' \
--data-raw '{
  "csvDefinition": {
    "csvText": "Channel,utm_source,utm_medium\nPaid Search,google|bing|duckduckgo,cpc|paid\nDirect,ANY,direct",
    "operatorsMap": {"utm_source": "IS", "utm_medium": "IS"},
    "columnMetadata": {"utm_source": "event_property", "utm_medium": "event_property"},
    "anyKeyword": "ANY",
    "separator": "|",
    "propertyMetadata": {},
    "useWaterfallLogic": true
  }
}'
```

```bash HTTP
PATCH /api/2/channel-classifiers/utm_channels HTTP/1.1
Host: amplitude.com
Authorization: Basic {api-key}:{secret-key} #credentials must be base64 encoded
Content-Type: application/json

{
  "csvDefinition": {
    "csvText": "Channel,utm_source,utm_medium\nPaid Search,google|bing|duckduckgo,cpc|paid\nDirect,ANY,direct",
    "operatorsMap": {"utm_source": "IS", "utm_medium": "IS"},
    "columnMetadata": {"utm_source": "event_property", "utm_medium": "event_property"},
    "anyKeyword": "ANY",
    "separator": "|",
    "propertyMetadata": {},
    "useWaterfallLogic": true
  }
}
```
{% /code-group %}

### Path parameters

| Parameter | Description                                                                               |
| --------- | ----------------------------------------------------------------------------------------- |
| `name`    | Required. String. The classifier's `derivedPropertyName`, exactly as returned by the [list endpoint](#list-classifiers). Must already exist in this project. Classifiers created in the Amplitude UI have a UUID identifier. |

### Body parameters

| Parameter       | Description                                                                                                         |
| --------------- | ------------------------------------------------------------------------------------------------------------------- |
| `displayName`   | Optional. String, max 1000 chars. When you set it, replaces the current `displayName`. Omit to leave it unchanged.  |
| `description`   | Optional. String, max 1000 chars. When you set it, replaces the current `description`.                              |
| `csvDefinition` | Required. Object. Full replacement of the existing definition. Go to [csvDefinition fields](#csvdefinition-fields). |

### Response

```json
{
  "status": "updated",
  "name": "utm_channels"
}
```

### Error responses

- `400` - Body missing `csvDefinition`, missing `csvDefinition.csvText`, or `displayName`/`description` longer than 1000 chars.
- `401` - Missing or malformed `Authorization` header.
- `403` - Invalid API key or secret.
- `404` - Classifier with that name not found.
- `413` - `csvDefinition.csvText` is larger than 1 MB.

## csvDefinition fields

The `csvDefinition` object describes the classifier rules. Its shape is the same on `POST` and `PATCH`.

| Parameter                 | Description                                                                                                                                                                                                                                                                                                                                                |
| ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | ---------------------------------------------------------------------------------------------------- |
| `csvText`                 | Required. String, max 1 MB. The raw CSV exactly as the UI builds it. The first column holds the resulting channel name; subsequent columns are property rules. Cells split on `separator` for multi-value matches. Use `anyKeyword` (default `ANY`) to mean "match any value". When `useWaterfallLogic` is `true`, Amplitude evaluates rows top-to-bottom. |
| `operatorsMap`            | Optional. Object. Maps each property column name to a comparison operator (for example, `{"utm_medium": "IS"}`). Defaults to exact-match (`IS`) when omitted.                                                                                                                                                                                              |
| `columnMetadata`          | Optional. Object. Maps each property column name to its property type — `event_property`, `user_property`, or `group_property`.                                                                                                                                                                                                                            |
| `columnMetadataGroupType` | Optional. Object. Maps each property column name to a group type, when the column refers to a group property.                                                                                                                                                                                                                                              |
| `anyKeyword`              | Optional. String. The keyword that means "match any value" inside a cell. Defaults to `ANY`.                                                                                                                                                                                                                                                               |
| `separator`               | Optional. String. The string that separates multi-value cells (for example, `                                                                                                                                                                                                                                                                              | `to express`google | bing` as "either google or bing"). Pick something that doesn't appear inside actual property values. |
| `propertyMetadata`        | Optional. Object. Advanced. Pre-built per-property metadata that overrides what Amplitude would otherwise derive from `operatorsMap` + `columnMetadata`. Most callers leave this as `{}` and let Amplitude derive it.                                                                                                                                      |
| `useWaterfallLogic`       | Optional. Boolean. When `true`, Amplitude evaluates rows top-to-bottom and the first matching row wins. When `false`, Amplitude evaluates rows independently. Defaults to `false`.                                                                                                                                                                         |

## Common patterns

### Broadcasting one definition to N projects

The classic use case for this API: apply a single canonical CSV to several sibling Amplitude projects (for example, one project per country). Hold the CSV in your tool, then loop through each project's `(api-key, secret-key)` pair and send a `PATCH` (or `POST` for projects that don't yet have the classifier).

The API has no built-in bulk endpoint; iterate over projects from your tool.

### Using waterfall logic for attribution

When ordering matters — for example, a row that captures Paid Search must take precedence over a generic Email row that would otherwise also match — set `useWaterfallLogic` to `true`. Amplitude then evaluates rows top-to-bottom and the first match wins. To evaluate every row independently, leave it `false`.

### Multi-value cells

To express "any of these values", use the `separator` you configured (for example, `|`):

```csv
Paid Search,google|bing|duckduckgo,cpc|paid
```

A cell of `google|bing|duckduckgo` matches if the property value is any of those three.
