> This page is for Gateway.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.merge.dev/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.merge.dev/_mcp/server.

# List Classifiers

GET https://api-gateway.merge.dev/v1/classifiers

List the organization's custom complexity classifiers, all in one page.

Reference: https://docs.merge.dev/merge-gateway/management-api/routing-policies/list-routing-classifiers

## Authentication

- `Authorization` header (bearer token, required) — A management key (`mgmt_...`), sent as `Authorization: Bearer <key>`. Reading /v1/routing-policies also accepts the organization's gateway API keys; writing there needs a management key.

## Response

### 200

The organization's classifiers

- `next` (string, required, nullable) — Always null: the list comes in one page.
- `previous` (string, required, nullable) — Always null: paging only goes forward.
- `results` (list of ClassifierV1Response, required) — The classifiers.

## Errors

### 401 Unauthorized Error

The key is missing or invalid.

- `detail` (ErrorResponseDetail, required) — A message, or an object with a `code` to branch on and a `message`.

### 403 Forbidden Error

The key lacks the scope this route needs, or the change is not allowed.

- `detail` (ErrorResponseDetail, required) — A message, or an object with a `code` to branch on and a `message`.

## Types

### ClassifierV1Response

A custom complexity classifier: your definition of simple and complex requests.

- `build_error` (string, required, nullable) — Why the last build failed, when `status` is `failed`.
- `created_at` (datetime, required)
- `description` (string, required, nullable) — What the classifier is for.
- `examples` (list of ClassifierExampleV1, required) — Labeled prompts: what your requests look like and how complex each one is, from 0 (simple) to 1 (complex). Scores further from 0.5 count more. The classifier is ready once at least 3 are below 0.5 and 3 are at or above it.
- `has_readout` (boolean, required) — Whether routers that score with the difficulty readout use it too. Classifiers saved before readouts get one when their examples are next updated.
- `id` (string, required) — Send as a routing policy's `complexity_classifier_id` to use it.
- `is_ready` (boolean, required) — Whether it has a build that scores requests (also true while a rebuild runs). A policy using a classifier that isn't ready scores with the built-in scorer.
- `name` (string, required) — Unique within the organization.
- `quality_report` (ClassifierQualityV1, required, nullable) — null until the classifier is ready.
- `status` (enum, required) — `building` while the classifier builds in the background after a save (a few seconds to a minute), then `ready`, or `not_enough_examples` when either side of 0.5 has fewer than 3 examples, or `failed`. While a rebuild runs, policies keep using the previous build.
  - Allowed values: `building`, `ready`, `not_enough_examples`, `failed`
- `updated_at` (datetime, required)

### ErrorResponseDetail

A message, or an object with a `code` to branch on and a `message`.

- string
- ErrorDetail: ErrorDetail

### ClassifierExampleV1

A labeled prompt.

- `complexity` (double, required) — How complex it is: 0 is simple, 1 is complex.
- `prompt` (string, required) — A prompt like the ones you send.

### ClassifierQualityV1

How well the classifier separates its own examples, measured when it was built. Each example is scored by the classifier rebuilt without it, so accuracy reflects prompts it hasn't seen. The built-in scorer's results on the same examples are the baseline.

- `accuracy` (double, required) — Share of examples scored on the right side of 0.5, from 0 to 1.
- `auc` (double, required, nullable) — Chance a complex example outscores a simple one, from 0 to 1.
- `examples` (integer, required) — Examples measured.
- `flagged_examples` (list of FlaggedExampleV1, required) — Up to 10 examples scored on the wrong side of their label: mislabeled, or unlike the rest of their side.
- `generic_accuracy` (double, required, nullable) — `accuracy` of the built-in scorer on the same examples.
- `generic_auc` (double, required, nullable) — `auc` of the built-in scorer on the same examples.
- `one_sided_terms` (OneSidedTermsV1, required) — Terms only one side uses.
- `warnings` (list of string, required) — What to change, if anything.

### ErrorDetail

A structured error. Some carry extra fields, like `count`.

- `code` (string, required) — A stable code to branch on, like `payment_method_required`.
- `message` (string, required) — A human-readable explanation.

### FlaggedExampleV1

- `complexity` (double, required) — The example's label.
- `index` (integer, required) — The example's position in `examples`, from 0.
- `prompt` (string, required) — The example's prompt, cut to 200 characters.
- `score` (double, required) — Its score from the classifier rebuilt without it.

### OneSidedTermsV1

- `complex` (list of string, required) — Terms only complex examples use. A simple request that mentions one may be scored complex; add simple examples that use them.
- `simple` (list of string, required) — Terms only simple examples use. A complex request that mentions one may be scored simple; add complex examples that use them.

## Examples

**Response**

```json
{
  "next": null,
  "previous": null,
  "results": [
    {
      "build_error": null,
      "created_at": "2026-06-02T17:04:00Z",
      "description": "What counts as complex for the finance team.",
      "examples": [
        {
          "complexity": 0.05,
          "prompt": "What was our ARR at the end of Q3?"
        },
        {
          "complexity": 0.1,
          "prompt": "Who owns the intercompany elimination entries this quarter?"
        },
        {
          "complexity": 0.05,
          "prompt": "Send me the link to the FY26 opex budget."
        },
        {
          "complexity": 0.95,
          "prompt": "Reconcile Q3 deferred revenue against the billing schedules and explain every variance over $5k."
        },
        {
          "complexity": 0.9,
          "prompt": "Build the ARR bridge from Q2 to Q3 and tie it back to the GAAP revenue waterfall."
        },
        {
          "complexity": 0.95,
          "prompt": "Walk through the ASC 606 treatment of a 3-year ramp deal with a free first quarter."
        }
      ],
      "has_readout": true,
      "id": "5d7f9b1c-3e5a-4c7e-9a1b-6c8e0a2c4e69",
      "is_ready": true,
      "name": "Finance requests",
      "quality_report": {
        "accuracy": 1,
        "auc": 1,
        "examples": 6,
        "flagged_examples": [],
        "generic_accuracy": 0.83,
        "generic_auc": 0.89,
        "one_sided_terms": {
          "complex": [
            "revenue"
          ],
          "simple": []
        },
        "warnings": [
          "Add more examples: 10 or more on each side give steadier scores"
        ]
      },
      "status": "ready",
      "updated_at": "2026-09-14T09:30:00Z"
    }
  ]
}
```

**SDK Code**

```python
import requests

url = "https://api-gateway.merge.dev/v1/classifiers"

headers = {"Authorization": "Bearer <token>"}

response = requests.get(url, headers=headers)

print(response.json())
```

```javascript
const url = 'https://api-gateway.merge.dev/v1/classifiers';
const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://api-gateway.merge.dev/v1/classifiers"

	req, _ := http.NewRequest("GET", url, nil)

	req.Header.Add("Authorization", "Bearer <token>")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://api-gateway.merge.dev/v1/classifiers")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.get("https://api-gateway.merge.dev/v1/classifiers")
  .header("Authorization", "Bearer <token>")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('GET', 'https://api-gateway.merge.dev/v1/classifiers', [
  'headers' => [
    'Authorization' => 'Bearer <token>',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://api-gateway.merge.dev/v1/classifiers");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <token>");
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = ["Authorization": "Bearer <token>"]

let request = NSMutableURLRequest(url: NSURL(string: "https://api-gateway.merge.dev/v1/classifiers")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```