Skip to main content
POST
/
v1
/
classify
Classify Comment
curl --request POST \
  --url https://api.trynawa.com/v1/classify
Classify a comment in one API call. Returns intent labels, sentiment, language, and a NAGL-generated analysis note. Semantic cache hits are free.
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

HeaderRequiredDescription
AuthorizationYesBearer nawa_live_sk_xxx or Bearer nawa_test_sk_xxx
Content-TypeYesapplication/json

Body

ParameterTypeRequiredDescription
textstringYesThe comment text to classify. Must be a non-empty string.

Query parameters

ParameterTypeRequiredDescription
providerstringNoForce 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": "متى الجزء الثاني؟"}'

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

FieldTypeDescription
idstringClassification ID in cls_nw_xxx format
objectstringAlways "classification"
intentstring[]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.
sentimentstringOne of positive, negative, neutral, mixed
languagestringDetected language: ar, en, or mixed
dialectstring | null"gulf" for any Arabic text, null for English. See dialect note below.
dialect_confidencenumber | nullA confidence score between 0 and 1 for Arabic text, null for English. See dialect note below.
requires_responsebooleanWhether the model judges this comment needs a reply
prioritystringOne of low, medium, high
suggested_reply.textstringNAGL’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.directionstring"rtl" for Arabic, "ltr" otherwise. Useful for UI rendering.
providerstringAI provider that produced this result: claude, allam, or gemini
modelstringSpecific model ID, e.g. claude-sonnet-4-5-20250929
fallback_usedbooleantrue if the primary provider failed and a fallback produced this result
tokens_usednumber | nullCurrently always null. Token accounting is planned; track usage via cost_usd for now.
cost_usdnumberAlways 0.006 for this endpoint
credits_usedintegerAlways 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

HeaderDescription
X-Request-IdUnique request identifier. Quote this to support when reporting an issue.
X-NAWA-CacheHIT if served from the semantic cache (free, no credit charge), MISS otherwise.
X-NAWA-ProviderWhich provider produced the response: claude, allam, gemini.
X-NAWA-LatencyServer-side latency in milliseconds.
X-NAWA-Calibration-VersionCalibration threshold version applied to this response. "default" when no custom calibration is set.
X-NAWA-Environmentsandbox for free keys, live for paid keys.
X-RateLimit-LimitYour tier’s per-minute request ceiling.
X-RateLimit-RemainingRequests remaining in the current one-minute window.
X-RateLimit-ResetRFC 3339 timestamp when the window resets.

Error responses

StatusTypeWhen
400invalid_request_errorMissing or empty text, invalid provider query param, malformed JSON body
401authentication_errorMissing, malformed, revoked, or expired API key
402insufficient_creditsLive key has insufficient credit balance for this request. Response body includes balance_credits and required_credits on the error object.
429rate_limit_errorPer-minute rate limit exceeded, or sandbox lifetime quota (100 requests) exhausted
500api_errorUnexpected internal failure. The response message is a generic constant; quote request_id to support for the underlying cause.
See Errors for the full envelope shape and all error codes.

More examples

Request:
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!"}'
Response:
{
  "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"
}
{
  "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"
}
{
  "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"
}