> 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.

# Get Classifier

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

Return a classifier with its examples and quality report.

Reference: https://docs.merge.dev/merge-gateway/management-api/routing-policies/get-routing-classifier

## 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.

## Request

### Path parameters

- `classifier_id` (string, required) — The classifier's `id`.

## Response

### 200

The classifier

- `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)

## 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`.

### 404 Not Found Error

The resource does not exist in the key's organization.

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

### 422 Unprocessable Entity Error

Validation Error

- `detail` (list of ValidationError, optional)

## Types

### 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.

### ErrorResponseDetail

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

- string
- ErrorDetail: ErrorDetail

### ValidationError

- `loc` (list of ValidationErrorLocItems, required)
- `msg` (string, required)
- `type` (string, required)
- `ctx` (ValidationErrorCtx, optional)
- `input` (any, optional)

### 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.

### 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.

### ValidationErrorLocItems

- string
- integer

### ValidationErrorCtx

## Examples

**Response**

```json
{
  "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/classifier_id"

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

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

print(response.json())
```

```javascript
const url = 'https://api-gateway.merge.dev/v1/classifiers/classifier_id';
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/classifier_id"

	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/classifier_id")

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/classifier_id")
  .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/classifier_id', [
  'headers' => [
    'Authorization' => 'Bearer <token>',
  ],
]);

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

```csharp
using RestSharp;

var client = new RestClient("https://api-gateway.merge.dev/v1/classifiers/classifier_id");
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/classifier_id")! 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()
```