AI · API reference
POST /v1/classify
Classifies a document into one or more of your labels and returns a confidence score for each.
The Atlas API is fictional. Endpoints, fields, and limits are illustrative.
POST https://api.atlas.example.com/v1/classify
OpenAPI: Download the OpenAPI spec (OpenAPI 3.1, YAML). The file is linted in CI and checked against this page.
Authentication
Send your API key in the Authorization header:
Authorization: Bearer YOUR_API_KEY
Requests without a valid key return 401 unauthorized.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
text | string | Yes | The document to classify. 1 to 100,000 characters. |
labels | array of strings | Yes | The labels to choose from. 2 to 50 labels, each up to 100 characters. |
multi_label | boolean | No | If true, the document can match more than one label. Default: false. |
threshold | number | No | Minimum confidence (0.0–1.0) for a label to count as a match. Default: 0.5. |
explain | boolean | No | If true, include a one-sentence reason for each match. Default: false. |
Unknown fields are rejected with 400 invalid_request.
Example request
The same request in curl, Python (with requests) and JavaScript (with fetch). The Atlas API is
fictional, so these calls return nothing real; they show the shape of a correct call. Each one
reads the key from the ATLAS_API_KEY environment variable instead of the source code.
- curl
- Python
- JavaScript
curl https://api.atlas.example.com/v1/classify \
-H "Authorization: Bearer $ATLAS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"text": "The left landing gear actuator leaked hydraulic fluid during the preflight check.",
"labels": ["hydraulics", "avionics", "propulsion", "structures"],
"multi_label": false,
"explain": true
}'
import os
import requests
response = requests.post(
"https://api.atlas.example.com/v1/classify",
headers={"Authorization": f"Bearer {os.environ['ATLAS_API_KEY']}"},
json={
"text": "The left landing gear actuator leaked hydraulic fluid during the preflight check.",
"labels": ["hydraulics", "avionics", "propulsion", "structures"],
"multi_label": False,
"explain": True,
},
timeout=30,
)
if not response.ok:
error = response.json()["error"]
raise SystemExit(f"{response.status_code} {error['type']}: {error['message']}")
result = response.json()
for match in result["matches"]:
print(match["label"], match["confidence"], match.get("reason", ""))
const response = await fetch("https://api.atlas.example.com/v1/classify", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.ATLAS_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
text: "The left landing gear actuator leaked hydraulic fluid during the preflight check.",
labels: ["hydraulics", "avionics", "propulsion", "structures"],
multi_label: false,
explain: true,
}),
});
if (!response.ok) {
const { error } = await response.json();
throw new Error(`${response.status} ${error.type}: ${error.message}`);
}
const result = await response.json();
for (const match of result.matches) {
console.log(match.label, match.confidence, match.reason ?? "");
}
Example response
{
"id": "cls_7f3a9c21",
"matches": [
{
"label": "hydraulics",
"confidence": 0.94,
"reason": "Describes a hydraulic fluid leak from a landing gear actuator."
}
],
"scores": {
"hydraulics": 0.94,
"structures": 0.31,
"avionics": 0.04,
"propulsion": 0.02
},
"model": "atlas-classify-2",
"usage": { "input_characters": 81 }
}
Response fields
| Field | Type | Description |
|---|---|---|
id | string | Unique ID for this request. Include it when you contact support. |
matches | array | Labels at or above threshold, highest confidence first. Empty if none qualify. |
matches[].label | string | The matched label. |
matches[].confidence | number | Confidence from 0.0 to 1.0. |
matches[].reason | string | Present only when explain is true. |
scores | object | Confidence for every label you sent, including those below threshold. |
model | string | The model version that produced the result. |
usage.input_characters | integer | Characters billed for this request. |
Confidence scores rank labels for this request only. A score of 0.94 does not mean the result is correct 94% of the time. To set a threshold for production, test the endpoint on your own labeled examples.
Errors
| HTTP status | error.type | Cause | What to do |
|---|---|---|---|
| 400 | invalid_request | A field is missing, unknown, or out of range | Check error.message for the field name |
| 401 | unauthorized | API key is missing or invalid | Check the Authorization header |
| 413 | text_too_long | text is over 100,000 characters | Split the document and classify each part |
| 429 | rate_limited | Too many requests | Wait for the time in the Retry-After header, then retry |
| 500 | server_error | Temporary problem on our side | Retry with exponential backoff |
Error responses use this shape:
{
"error": {
"type": "invalid_request",
"message": "labels must contain between 2 and 50 items."
}
}
Rate limits
| Plan | Requests per minute | Characters per day |
|---|---|---|
| Free | 20 | 500,000 |
| Team | 600 | 50,000,000 |
Every response includes two headers: X-RateLimit-Remaining (requests you can still make in the
current minute) and X-RateLimit-Reset (seconds until the window resets).