Classify Comment
curl --request POST \
--url https://api.trynawa.com/v1/classifyimport requests
url = "https://api.trynawa.com/v1/classify"
response = requests.post(url)
print(response.text)const options = {method: 'POST'};
fetch('https://api.trynawa.com/v1/classify', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));Endpoints
Classify Comment
Classify an Arabic or English comment by intent, sentiment, and language.
POST
/
v1
/
classify
Classify Comment
curl --request POST \
--url https://api.trynawa.com/v1/classifyimport requests
url = "https://api.trynawa.com/v1/classify"
response = requests.post(url)
print(response.text)const options = {method: 'POST'};
fetch('https://api.trynawa.com/v1/classify', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));Classify a comment in one API call. Returns intent labels, sentiment, language, and a NAGL-generated analysis note. Semantic cache hits are free.
See Errors for the full envelope shape and all error codes.
Cost: $0.006 per request (6 credits). Semantic cache hits are free (
X-NAWA-Cache: HIT) and do not decrement your credit balance.Request
Headers
| Header | Required | Description |
|---|---|---|
Authorization | Yes | Bearer nawa_live_sk_xxx or Bearer nawa_test_sk_xxx |
Content-Type | Yes | application/json |
Body
| Parameter | Type | Required | Description |
|---|---|---|---|
text | string | Yes | The comment text to classify. Must be a non-empty string. |
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
provider | string | No | Force a specific AI provider for A/B testing. One of claude, gemini, allam. Default: NAGL chooses based on detected language. |
Example request
curl -X POST https://api.trynawa.com/v1/classify \
-H "Authorization: Bearer nawa_test_sk_xxx" \
-H "Content-Type: application/json" \
-d '{"text": "متى الجزء الثاني؟"}'
import { Nawa } from '@nawalabs/sdk'
const nawa = new Nawa({ apiKey: process.env.NAWA_API_KEY })
const { data, error } = await nawa.classify({
text: 'متى الجزء الثاني؟',
})
from nawa import Nawa
nawa = Nawa(api_key="your_api_key")
result = nawa.classify(text="متى الجزء الثاني؟")
Response
Success response (200)
{
"result": {
"id": "cls_nw_lx4cqy2j2o1o",
"object": "classification",
"intent": ["question"],
"sentiment": "neutral",
"language": "ar",
"dialect": "gulf",
"dialect_confidence": 0.92,
"requires_response": true,
"priority": "medium",
"suggested_reply": {
"text": "Viewer is asking when the next part drops. Respond with the schedule.",
"direction": "rtl"
},
"provider": "claude",
"model": "claude-sonnet-4-5-20250929",
"fallback_used": false,
"tokens_used": null,
"cost_usd": 0.006,
"credits_used": 6
},
"success": true,
"errors": [],
"request_id": "req_nw_9cfb228162d6f8c3"
}
Result fields
| Field | Type | Description |
|---|---|---|
id | string | Classification ID in cls_nw_xxx format |
object | string | Always "classification" |
intent | string[] | One or more intent labels. Typical values: question, complaint, praise, suggestion, spam, other. The array may contain multiple labels when a comment expresses more than one intent. |
sentiment | string | One of positive, negative, neutral, mixed |
language | string | Detected language: ar, en, or mixed |
dialect | string | null | "gulf" for any Arabic text, null for English. See dialect note below. |
dialect_confidence | number | null | A confidence score between 0 and 1 for Arabic text, null for English. See dialect note below. |
requires_response | boolean | Whether the model judges this comment needs a reply |
priority | string | One of low, medium, high |
suggested_reply.text | string | NAGL’s natural-language analysis of the comment (the reasoning behind the classification). This is not a draft reply; use /v1/comments/reply for that. |
suggested_reply.direction | string | "rtl" for Arabic, "ltr" otherwise. Useful for UI rendering. |
provider | string | AI provider that produced this result: claude, allam, or gemini |
model | string | Specific model ID, e.g. claude-sonnet-4-5-20250929 |
fallback_used | boolean | true if the primary provider failed and a fallback produced this result |
tokens_used | number | null | Currently always null. Token accounting is planned; track usage via cost_usd for now. |
cost_usd | number | Always 0.006 for this endpoint |
credits_used | integer | Always 6 for this endpoint |
Dialect detection is a known limitation on
/v1/classify.
dialect is hardcoded to "gulf" for any Arabic text on this endpoint today; full dialect detection runs only on /v1/detect and /v1/translate. dialect_confidence exposes the NAGL intent classifier’s internal confidence, not a dialect-specific confidence. Treat the field as a rough signal until real dialect wiring lands. Use /v1/detect for authoritative dialect on Arabic text.Response headers
| Header | Description |
|---|---|
X-Request-Id | Unique request identifier. Quote this to support when reporting an issue. |
X-NAWA-Cache | HIT if served from the semantic cache (free, no credit charge), MISS otherwise. |
X-NAWA-Provider | Which provider produced the response: claude, allam, gemini. |
X-NAWA-Latency | Server-side latency in milliseconds. |
X-NAWA-Calibration-Version | Calibration threshold version applied to this response. "default" when no custom calibration is set. |
X-NAWA-Environment | sandbox for free keys, live for paid keys. |
X-RateLimit-Limit | Your tier’s per-minute request ceiling. |
X-RateLimit-Remaining | Requests remaining in the current one-minute window. |
X-RateLimit-Reset | RFC 3339 timestamp when the window resets. |
Error responses
| Status | Type | When |
|---|---|---|
| 400 | invalid_request_error | Missing or empty text, invalid provider query param, malformed JSON body |
| 401 | authentication_error | Missing, malformed, revoked, or expired API key |
| 402 | insufficient_credits | Live key has insufficient credit balance for this request. Response body includes balance_credits and required_credits on the error object. |
| 429 | rate_limit_error | Per-minute rate limit exceeded, or sandbox lifetime quota (100 requests) exhausted |
| 500 | api_error | Unexpected internal failure. The response message is a generic constant; quote request_id to support for the underlying cause. |
More examples
English praise
English praise
Request:Response:
curl -X POST https://api.trynawa.com/v1/classify \
-H "Authorization: Bearer nawa_test_sk_xxx" \
-H "Content-Type: application/json" \
-d '{"text": "This is hands down the best review I have seen on this phone. Subscribed!"}'
{
"result": {
"id": "cls_nw_en01praise",
"object": "classification",
"intent": ["praise"],
"sentiment": "positive",
"language": "en",
"dialect": null,
"dialect_confidence": null,
"requires_response": false,
"priority": "low",
"suggested_reply": {
"text": "Highly positive engagement from a new subscriber. No response required; consider pinning or hearting for social signal.",
"direction": "ltr"
},
"provider": "claude",
"model": "claude-sonnet-4-5-20250929",
"fallback_used": false,
"tokens_used": null,
"cost_usd": 0.006,
"credits_used": 6
},
"success": true,
"errors": [],
"request_id": "req_nw_en01praise"
}
English complaint (multi-intent)
English complaint (multi-intent)
{
"result": {
"id": "cls_nw_en02complaint",
"object": "classification",
"intent": ["complaint", "suggestion"],
"sentiment": "negative",
"language": "en",
"dialect": null,
"dialect_confidence": null,
"requires_response": true,
"priority": "medium",
"suggested_reply": {
"text": "Audio quality complaint with an implicit suggestion to fix. Acknowledge and commit to the next upload being better.",
"direction": "ltr"
},
"provider": "claude",
"model": "claude-sonnet-4-5-20250929",
"fallback_used": false,
"tokens_used": null,
"cost_usd": 0.006,
"credits_used": 6
},
"success": true,
"errors": [],
"request_id": "req_nw_en02complaint"
}
Arabic question
Arabic question
{
"result": {
"id": "cls_nw_ar01question",
"object": "classification",
"intent": ["question"],
"sentiment": "neutral",
"language": "ar",
"dialect": "gulf",
"dialect_confidence": 0.88,
"requires_response": true,
"priority": "medium",
"suggested_reply": {
"text": "Viewer asks when the next part drops. Reply with the schedule in the same dialect.",
"direction": "rtl"
},
"provider": "claude",
"model": "claude-sonnet-4-5-20250929",
"fallback_used": false,
"tokens_used": null,
"cost_usd": 0.006,
"credits_used": 6
},
"success": true,
"errors": [],
"request_id": "req_nw_ar01question"
}
Was this page helpful?
⌘I