Channel Classifier API
Authentication
This API uses 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.
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
| Region | Endpoint |
|---|---|
| Standard server | https://amplitude.com/api/2/channel-classifiers |
| EU residency server | https://analytics.eu.amplitude.com/api/2/channel-classifiers |
List classifiers
Returns every channel classifier in the authenticated project.
GET https://amplitude.com/api/2/channel-classifiers
curl --location --request GET 'https://amplitude.com/api/2/channel-classifiers' \
-u '{api-key}:{secret-key}'
Response
{
"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",
"lastModified": "2026-05-10T18:09:22.275499"
}
]
}
Error responses
401- Missing or malformedAuthorizationheader.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}
curl --location --request GET 'https://amplitude.com/api/2/channel-classifiers/utm_channels' \
-u '{api-key}:{secret-key}'
Path parameters
| Parameter | Description |
|---|---|
name | Required. String. The classifier's stable identifier (the derivedPropertyName). Letters, digits, and underscores only. |
Response
{
"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",
"lastModified": "2026-05-10T18:09:22.275499"
}
Error responses
401- Missing or malformedAuthorizationheader.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}
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
}
}'
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, and underscores 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. |
Response
{
"status": "created",
"name": "utm_channels"
}
Error responses
400- Body missingcsvDefinition, missingcsvDefinition.csvText, ordisplayName/descriptionlonger than 1000 chars.401- Missing or malformedAuthorizationheader.403- Invalid API key or secret.409- Classifier with that name already exists in this project.413-csvDefinition.csvTextis 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}
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
}
}'
Path parameters
| Parameter | Description |
|---|---|
name | Required. String. The classifier's stable identifier. Must already exist in this project. |
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. |
Response
{
"status": "updated",
"name": "utm_channels"
}
Error responses
400- Body missingcsvDefinition, missingcsvDefinition.csvText, ordisplayName/descriptionlonger than 1000 chars.401- Missing or malformedAuthorizationheader.403- Invalid API key or secret.404- Classifier with that name not found.413-csvDefinition.csvTextis 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, ` |
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, |):
Paid Search,google|bing|duckduckgo,cpc|paid
A cell of google|bing|duckduckgo matches if the property value is any of those three.
Was this helpful?