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, detected language and Arabic dialect, a suggested reply in the commenter’s own dialect, and the reasoning behind the classification.
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. Default: chosen by language routing. |
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.95,
"requires_response": true,
"priority": "medium",
"suggested_reply": {
"text": "يعطيك العافية يا غالي 🙏 الجزء الثاني قريب إن شاء الله، خلك متابع عشان ما يفوتك!",
"direction": "rtl"
},
"reasoning": "The comment asks when the next part is released, which needs a direct answer rather than a reaction.",
"provider": "claude",
"model": "claude-haiku-4-5-20251001",
"fallback_used": false,
"tokens_used": 988,
"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 | Detected Arabic dialect: gulf, egyptian, levantine or msa. null for non-Arabic text. |
dialect_confidence | number | null | Confidence in the detected dialect, 0 to 1. null for non-Arabic text. |
requires_response | boolean | Whether the model judges this comment needs a reply |
priority | string | One of low, medium, high |
suggested_reply.text | string | A draft reply, written in the commenter’s own language and dialect. Empty string when the classification decided the comment needs a reaction rather than a reply. |
suggested_reply.direction | string | "rtl" for Arabic, "ltr" otherwise. Useful for UI rendering. |
reasoning | string | null | Why the classifier chose this action. Useful for review queues and for tuning your own thresholds. |
provider | string | AI provider that produced this result: claude or gemini |
model | string | The model that actually ran, e.g. claude-haiku-4-5-20251001. Classification runs on Haiku for cost; reply generation may use a larger model. |
fallback_used | boolean | true if the primary provider failed and a fallback produced this result |
tokens_used | number | null | Input plus output tokens across classification and reply generation. null only when no model call was made. |
cost_usd | number | Always 0.006 for this endpoint |
credits_used | integer | Always 6 for this endpoint |
Changed 2026-09-13. Three fields on this endpoint used to be placeholders and are now real:
dialect was hardcoded to "gulf" for all Arabic, dialect_confidence returned the classifier’s overall confidence rather than a dialect score, and suggested_reply.text returned internal reasoning instead of a reply. If you built around any of those, re-read the table above. The reasoning moved to its own reasoning field.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 or 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?