Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion api-reference/classify.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ result = nawa.classify(text="متى الجزء الثاني؟")
| `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.text` | string | NAGL's natural-language analysis of the comment (the reasoning behind the classification). This is not a draft reply; use `POST /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` |
Expand Down
216 changes: 182 additions & 34 deletions api-reference/comments-reply.mdx
Original file line number Diff line number Diff line change
@@ -1,60 +1,97 @@
---
title: "Reply to Comment"
sidebarTitle: "POST /v1/comments/:id/reply"
description: "Generate a context-aware reply to a comment in Arabic or English."
api: "POST https://api.trynawa.com/v1/comments/{id}/reply"
title: "Reply to comment"
sidebarTitle: "POST /v1/comments/reply"
description: "Classify a comment and generate a context-aware reply in a single call."
api: "POST https://api.trynawa.com/v1/comments/reply"
---

Generate an AI-powered reply that matches the commenter's language and cultural context. For Arabic comments, replies match the detected dialect (Gulf, Egyptian, Levantine, MSA). For English comments, replies are natural and platform-appropriate. Language is auto-detected unless overridden.
Classify a comment and generate a context-aware reply in one call. For Arabic comments, replies match the detected dialect (Gulf, Egyptian, Levantine, MSA). For English comments, replies are natural and platform-appropriate. Supports tone control and max length configuration.

<Note>
Cost: **$0.008** per request (8 credits). Semantic cache hits are free (`X-NAWA-Cache: HIT`).
</Note>

## Request

### Path parameters
### Headers

| Header | Required | Description |
|--------|----------|-------------|
| `Authorization` | Yes | `Bearer nawa_live_sk_xxx` or `Bearer nawa_test_sk_xxx` |
| `Content-Type` | Yes | `application/json` |

### Body parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | string | Yes | The comment ID to reply to. |
| `text` | string | Yes | The comment text to classify and reply to. |
| `tone` | string | No | Reply tone: `friendly`, `professional`, `casual`, `formal`. Default: `professional`. |
| `max_length` | integer | No | Maximum reply length in characters (1-2000). Default: `500`. |
| `context` | object | No | Additional context to improve reply quality. |
| `context.platform` | string | No | Source platform for context. |
| `context.brand_voice` | string | No | Brand voice description to match. |

### Body parameters
### Query parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `tone` | string | No | Reply tone: `friendly`, `professional`, `casual`, `formal`. Default: `friendly`. |
| `max_length` | integer | No | Maximum reply length in characters. Default: 500. |
| `context` | string | No | Additional context about the channel or video to improve reply relevance. |
| `language` | string | No | Force reply language: `ar`, `en`, `auto`. Default: `auto` (matches commenter's language). |
| `provider` | string | No | Force a specific AI provider: `claude`, `gemini`, `allam`. Default: NAGL chooses based on detected language. |

### Example request

<CodeGroup>

```bash cURL
curl -X POST https://api.trynawa.com/v1/comments/cmt_abc123/reply \
curl -X POST https://api.trynawa.com/v1/comments/reply \
-H "Authorization: Bearer nawa_test_sk_xxx" \
-H "Content-Type: application/json" \
-d '{
"tone": "friendly",
"context": "Tech review channel focused on smartphones"
"text": "هذا المنتج سيء جداً ولا أنصح به",
"tone": "professional",
"max_length": 500,
"context": {
"platform": "youtube",
"brand_voice": "helpful and empathetic"
}
}'
```

```typescript TypeScript
const { data, error } = await nawa.comments.reply('cmt_abc123', {
tone: 'friendly',
context: 'Tech review channel focused on smartphones'
import { Nawa } from '@nawalabs/sdk'

const nawa = new Nawa({ apiKey: process.env.NAWA_API_KEY })

const { data, error } = await nawa.comments.reply({
text: 'هذا المنتج سيء جداً ولا أنصح به',
tone: 'professional',
maxLength: 500,
context: {
platform: 'youtube',
brandVoice: 'helpful and empathetic'
}
})

console.log(data.reply.text)
console.log(data.reply.direction) // "rtl" for Arabic
```

```python Python
from nawa import Nawa

nawa = Nawa(api_key="your_api_key")

result = nawa.comments.reply(
comment_id="cmt_abc123",
tone="friendly",
context="Tech review channel focused on smartphones"
text="هذا المنتج سيء جداً ولا أنصح به",
tone="professional",
max_length=500,
context={
"platform": "youtube",
"brand_voice": "helpful and empathetic"
}
)

print(result.data.reply["text"])
print(result.data.reply["direction"])
```

</CodeGroup>
Expand All @@ -67,25 +104,136 @@ result = nawa.comments.reply(
{
"success": true,
"result": {
"comment_id": "cmt_abc123",
"reply_text": "إن شاء الله الجزء الثاني قريب! تابعنا عشان ما يفوتك 🔔",
"reply_dialect": "gulf",
"tone": "friendly",
"original_intent": "question",
"original_dialect": "gulf"
"id": "rpl_nw_a1b2c3d4e5f6",
"object": "comment_reply",
"classification": {
"intent": ["complaint"],
"sentiment": "negative",
"priority": "high",
"requires_response": true
},
"reply": {
"text": "نعتذر عن تجربتك السلبية. نود مساعدتك بشكل أفضل، هل يمكنك مشاركة تفاصيل المشكلة؟",
"direction": "rtl",
"tone": "professional"
},
"provider": "claude",
"model": "claude-sonnet-4-5-20250929",
"cost_usd": 0.008,
"credits_used": 8
},
"errors": [],
"request_id": "req_rep789xyz012"
"request_id": "req_nw_rpl01abc23def4"
}
```

### Result fields

| Field | Type | Description |
|-------|------|-------------|
| `comment_id` | string | The comment that was replied to |
| `reply_text` | string | The generated reply text |
| `reply_dialect` | string \| null | Dialect used in the reply (matches original). `null` for English replies. |
| `tone` | string | The tone used for the reply |
| `original_intent` | string | Detected intent of the original comment |
| `original_dialect` | string | Detected dialect of the original comment |
| `id` | string | Reply ID in `rpl_nw_xxx` format |
| `object` | string | Always `"comment_reply"` |
| `classification.intent` | string[] | Detected intents from the original comment |
| `classification.sentiment` | string | Detected sentiment: `positive`, `negative`, `neutral`, `mixed` |
| `classification.priority` | string | Priority level: `low`, `medium`, `high` |
| `classification.requires_response` | boolean | Whether the model judges this comment needs a reply |
| `reply.text` | string | The generated reply text |
| `reply.direction` | string | Text direction: `rtl` for Arabic, `ltr` for English |
| `reply.tone` | string | The tone used for the reply |
| `provider` | string | AI provider: `claude`, `allam`, or `gemini` |
| `model` | string | Specific model ID |
| `cost_usd` | number | Always `0.008` for this endpoint |
| `credits_used` | integer | Always `8` for this endpoint |

### Response headers

| Header | Description |
|--------|-------------|
| `X-Request-Id` | Unique request identifier. Quote this to support when reporting an issue. |
| `X-NAWA-Provider` | Which provider produced the response: `claude`, `allam`, `gemini`. |
| `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 `tone`, `max_length` out of range, malformed JSON |
| 401 | `authentication_error` | Missing, malformed, revoked, or expired API key |
| 402 | `insufficient_credits` | Live key has insufficient credit balance |
| 429 | `rate_limit_error` | Per-minute rate limit exceeded, or free key lifetime quota exhausted |
| 500 | `api_error` | Unexpected internal failure. Quote `request_id` to support. |

See [Errors](/errors) for the full envelope shape and all error codes.

### More examples

<AccordionGroup>
<Accordion title="Arabic complaint with professional tone">
```json
{
"success": true,
"result": {
"id": "rpl_nw_complaint01",
"object": "comment_reply",
"classification": {
"intent": ["complaint"],
"sentiment": "negative",
"priority": "high",
"requires_response": true
},
"reply": {
"text": "نعتذر عن تجربتك السلبية. نود مساعدتك بشكل أفضل، هل يمكنك مشاركة تفاصيل المشكلة؟",
"direction": "rtl",
"tone": "professional"
},
"provider": "claude",
"model": "claude-sonnet-4-5-20250929",
"cost_usd": 0.008,
"credits_used": 8
},
"errors": [],
"request_id": "req_nw_rpl_complaint01"
}
```
</Accordion>

<Accordion title="English praise with friendly tone">
Request:
```bash
curl -X POST https://api.trynawa.com/v1/comments/reply \
-H "Authorization: Bearer nawa_test_sk_xxx" \
-H "Content-Type: application/json" \
-d '{"text": "Love your content! Keep up the great work!", "tone": "friendly"}'
```

Response:
```json
{
"success": true,
"result": {
"id": "rpl_nw_praise01",
"object": "comment_reply",
"classification": {
"intent": ["praise"],
"sentiment": "positive",
"priority": "low",
"requires_response": false
},
"reply": {
"text": "Thank you so much! Really appreciate you watching. More content coming soon!",
"direction": "ltr",
"tone": "friendly"
},
"provider": "claude",
"model": "claude-sonnet-4-5-20250929",
"cost_usd": 0.008,
"credits_used": 8
},
"errors": [],
"request_id": "req_nw_rpl_praise01"
}
```
</Accordion>
</AccordionGroup>
67 changes: 51 additions & 16 deletions api-reference/health.mdx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: "Health Check"
title: "Health check"
sidebarTitle: "GET /v1/health"
description: "Check the operational status of the NAWA API and its dependencies."
api: "GET https://api.trynawa.com/v1/health"
Expand All @@ -22,41 +22,76 @@ curl https://api.trynawa.com/v1/health
"success": true,
"result": {
"status": "healthy",
"version": "1.0.0",
"version": "v1",
"services": {
"api": "operational",
"classification": "operational",
"database": "operational",
"cache": "operational"
"database": {
"status": "healthy",
"latency_ms": 12
},
"redis": {
"status": "healthy",
"latency_ms": 3
},
"nagl": {
"status": "healthy",
"latency_ms": 8
}
},
"timestamp": "2025-01-15T12:00:00Z"
"timestamp": "2026-04-20T12:00:00Z",
"latency_ms": 15
},
"errors": [],
"request_id": "req_hlt_abc123"
"request_id": "req_nw_hlt1a2b3c4d5e"
}
```

### Degraded response (200)
### Degraded response (503)

When one or more services are unhealthy, the endpoint returns HTTP 503:

```json
{
"success": true,
"result": {
"status": "degraded",
"version": "1.0.0",
"version": "v1",
"services": {
"api": "operational",
"classification": "degraded",
"database": "operational",
"cache": "operational"
"database": {
"status": "healthy",
"latency_ms": 14
},
"redis": {
"status": "degraded",
"latency_ms": 450
},
"nagl": {
"status": "healthy",
"latency_ms": 9
}
},
"timestamp": "2025-01-15T12:00:00Z"
"timestamp": "2026-04-20T12:00:00Z",
"latency_ms": 460
},
"errors": [],
"request_id": "req_hlt_def456"
"request_id": "req_nw_hlt_def456"
}
```

### Result fields

| Field | Type | Description |
|-------|------|-------------|
| `status` | string | Overall status: `healthy` or `degraded` |
| `version` | string | API version identifier |
| `services` | object | Per-service health checks |
| `services.database` | object | PostgreSQL database status and latency |
| `services.redis` | object | Redis cache status and latency |
| `services.nagl` | object | NAGL classification engine status and latency |
| `services.*.status` | string | `healthy`, `degraded`, or `down` |
| `services.*.latency_ms` | integer | Service response time in milliseconds |
| `timestamp` | string | ISO 8601 timestamp of the health check |
| `latency_ms` | integer | Total health check latency in milliseconds |

<Note>
For real-time status monitoring, visit [status.trynawa.com](https://status.trynawa.com).
</Note>
2 changes: 1 addition & 1 deletion api-reference/usage.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ curl "https://api.trynawa.com/v1/usage?from=2025-01-01T00:00:00Z&group_by=endpoi
"avg_latency_ms": 650
},
{
"endpoint": "/v1/comments/:id/reply",
"endpoint": "/v1/comments/reply",
"requests": 1750,
"cost": 14.00,
"cache_hits": 0,
Expand Down
Loading