From 33ce872174a11408086b66d0ac16c0bff3e76436 Mon Sep 17 00:00:00 2001 From: "mintlify[bot]" <109931778+mintlify[bot]@users.noreply.github.com> Date: Mon, 20 Apr 2026 18:28:34 +0000 Subject: [PATCH] docs: add processing_status and error recovery documentation Document the processing_status and error_message fields on GET /v1/comments, update the classification.failed webhook event with a payload example, add comment processing error recovery guidance to the errors page, and add an error recovery section to the batch processing guide. Reflects backend fix in sunnybhara/nawa-ai-spark@09871a2 that ensures processing_status is always reset to failed on uncaught errors. Generated-By: mintlify-agent --- api-reference/comments-list.mdx | 36 ++++++++++++++++++++- errors.mdx | 42 +++++++++++++++++++++++++ guides/batch-processing.mdx | 56 +++++++++++++++++++++++++++++++++ openapi.yaml | 24 ++++++++++++++ webhooks.mdx | 24 +++++++++++++- 5 files changed, 180 insertions(+), 2 deletions(-) diff --git a/api-reference/comments-list.mdx b/api-reference/comments-list.mdx index 1e18d08..9067bd0 100644 --- a/api-reference/comments-list.mdx +++ b/api-reference/comments-list.mdx @@ -19,9 +19,10 @@ Retrieve classified comments with filtering and pagination. This endpoint is **f | `sentiment` | string | No | Filter by sentiment: `positive`, `negative`, `neutral`, `mixed` | | `dialect` | string | No | Filter by dialect: `gulf`, `egyptian`, `levantine`, `msa` | | `toxicity` | string | No | Filter by toxicity: `none`, `mild`, `moderate`, `severe` | +| `processing_status` | string | No | Filter by processing state: `pending`, `processing`, `completed`, `failed`, `auto_executed`, `retry_pending` | | `from` | string | No | Start date (ISO 8601): `2025-01-01T00:00:00Z` | | `to` | string | No | End date (ISO 8601): `2025-01-31T23:59:59Z` | -| `limit` | integer | No | Results per page (1–100). Default: 25. | +| `limit` | integer | No | Results per page (1-100). Default: 25. | | `cursor` | string | No | Pagination cursor from previous response. | ### Example request @@ -77,6 +78,8 @@ for comment in nawa.comments.list(platform="youtube"): "sentiment": "neutral", "dialect": "gulf", "toxicity": "none", + "processing_status": "completed", + "error_message": null, "created_at": "2025-01-15T10:30:00Z", "channel_id": "ch_123" } @@ -91,3 +94,34 @@ for comment in nawa.comments.list(platform="youtube"): "request_id": "req_lst_abc123" } ``` + +### Result fields + +| Field | Type | Description | +|-------|------|-------------| +| `id` | string | Unique comment identifier | +| `text` | string | The comment text | +| `platform` | string | Source platform: `youtube`, `instagram`, `twitter`, `facebook` | +| `intent` | string | Classified intent label | +| `sentiment` | string | Detected sentiment | +| `dialect` | string | Detected Arabic dialect, if applicable | +| `toxicity` | string | Toxicity severity level | +| `processing_status` | string | Current processing state (see table below) | +| `error_message` | string \| null | Error description when processing failed. `null` on success. | +| `created_at` | string | ISO 8601 timestamp of comment creation | +| `channel_id` | string | Channel or account the comment belongs to | + +### Processing status values + +| Status | Description | +|--------|-------------| +| `pending` | Comment is queued for classification | +| `processing` | Classification is actively running | +| `completed` | Successfully classified and ready for review | +| `failed` | Classification failed. Check `error_message` for details. | +| `auto_executed` | Classified and automatically actioned (reply, heart, or skip) | +| `retry_pending` | Failed with a transient error (e.g. provider timeout) and queued for automatic retry | + + + Filter for `processing_status=failed` to find comments that need reprocessing. Failed comments always include an `error_message` with the failure reason, making it straightforward to diagnose and retry. + diff --git a/errors.mdx b/errors.mdx index fdcf365..e638232 100644 --- a/errors.mdx +++ b/errors.mdx @@ -267,11 +267,53 @@ An unexpected error occurred on the NAWA side. "suggested_action": "Retry after a few seconds. Check status.trynawa.com for updates." } ``` + + When a provider failure occurs during comment processing, the comment's `processing_status` is set to `failed` and the `error_message` field contains the failure reason. This ensures the comment is never stuck in a `processing` state and can be retried. Transient failures (e.g. rate limits from the upstream provider) set `processing_status` to `retry_pending` and are automatically retried. --- +## Comment processing error recovery + +When NAWA processes a comment (via classification, reply generation, or batch processing), the comment's `processing_status` field tracks its lifecycle. If an error occurs at any point during processing, the status is automatically set to `failed` with a descriptive `error_message`. + +| Processing status | Meaning | Action | +|-------------------|---------|--------| +| `failed` | A permanent error occurred (invalid input, access denied) | Investigate `error_message`, fix the issue, and reclassify | +| `retry_pending` | A transient error occurred (provider timeout, upstream rate limit) | NAWA automatically retries these. No action needed. | + +You can query failed comments and retry them: + + + +```bash cURL +curl "https://api.trynawa.com/v1/comments?processing_status=failed&limit=50" \ + -H "Authorization: Bearer nawa_live_sk_xxx" +``` + +```typescript TypeScript +const { data } = await nawa.comments.list({ + processing_status: 'failed', + limit: 50 +}) + +for (const comment of data.comments) { + console.log(`${comment.id}: ${comment.error_message}`) +} +``` + +```python Python +result = nawa.comments.list(processing_status="failed", limit=50) + +for comment in result.data["comments"]: + print(f"{comment['id']}: {comment['error_message']}") +``` + + + +--- + ## Handling errors in code diff --git a/guides/batch-processing.mdx b/guides/batch-processing.mdx index b938ea3..21f4575 100644 --- a/guides/batch-processing.mdx +++ b/guides/batch-processing.mdx @@ -177,3 +177,59 @@ Estimate batch cost before processing: Always respect the `X-RateLimit-Remaining` header. If it reaches 0, wait until `X-RateLimit-Reset` before sending more requests. + +## Error recovery + +After a batch run, some comments may end up with `processing_status` set to `failed`. NAWA automatically resets stuck comments so they never stay in `processing` state. You can query for failed comments and retry them. + +### Fetching failed comments + + + +```bash cURL +curl "https://api.trynawa.com/v1/comments?processing_status=failed&limit=100" \ + -H "Authorization: Bearer nawa_live_sk_xxx" +``` + +```typescript TypeScript +const { data } = await nawa.comments.list({ + processing_status: 'failed', + limit: 100 +}) + +console.log(`${data.comments.length} comments failed`) +for (const c of data.comments) { + console.log(` ${c.id}: ${c.error_message}`) +} +``` + +```python Python +result = nawa.comments.list(processing_status="failed", limit=100) + +print(f"{len(result.data['comments'])} comments failed") +for c in result.data["comments"]: + print(f" {c['id']}: {c['error_message']}") +``` + + + +### Retrying failed comments + +Re-classify failed comments by passing them through the same batch pipeline. Comments with `retry_pending` status are automatically retried by NAWA and do not need manual intervention. + +```typescript +const failed = await nawa.comments.list({ processing_status: 'failed', limit: 100 }) + +const retryBatch = failed.data.comments.map(c => ({ + id: c.id, + text: c.text, + platform: c.platform +})) + +const retryResults = await processBatch(retryBatch, 3) // lower concurrency for retries +console.log(`Retried ${retryResults.length} comments`) +``` + + + Use the `classification.failed` [webhook event](/webhooks) to get real-time notifications when comments fail processing, instead of polling. + diff --git a/openapi.yaml b/openapi.yaml index 2c6201d..db9d84f 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -977,6 +977,13 @@ paths: type: string enum: [none, mild, moderate, severe] description: Filter by toxicity + - name: processing_status + in: query + required: false + schema: + type: string + enum: [pending, processing, completed, failed, auto_executed, retry_pending] + description: Filter by processing state - name: from in: query required: false @@ -1030,6 +1037,8 @@ paths: sentiment: neutral dialect: gulf toxicity: none + processing_status: completed + error_message: null created_at: "2025-01-15T10:30:00Z" channel_id: ch_123 pagination: @@ -2076,6 +2085,21 @@ components: toxicity: type: string enum: [none, mild, moderate, severe] + processing_status: + type: string + enum: [pending, processing, completed, failed, auto_executed, retry_pending] + description: | + Current processing state. `pending` = awaiting classification, + `processing` = classification in progress, `completed` = successfully + classified, `failed` = classification failed (see `error_message`), + `auto_executed` = classified and auto-actioned, `retry_pending` = + failed with a transient error and queued for retry. + error_message: + type: string + nullable: true + description: | + Human-readable error description when `processing_status` is `failed` + or `retry_pending`. Null when processing succeeded. created_at: type: string format: date-time diff --git a/webhooks.mdx b/webhooks.mdx index 2ef4922..28735ea 100644 --- a/webhooks.mdx +++ b/webhooks.mdx @@ -11,14 +11,20 @@ Receive real-time notifications when events occur in your NAWA account. Webhooks | Event | Description | Trigger | |-------|-------------|---------| | `classification.completed` | A classification request succeeded | After `/v1/classify` completes | -| `classification.failed` | A classification request failed | On provider or internal errors | +| `classification.failed` | A classification request failed | On any provider, internal, or transient error | | `comment.new` | A new comment was ingested | When a connected platform receives a comment | | `comment.replied` | A reply was posted | After `/v1/comments/:id/reply` succeeds | | `credits.low` | Credit balance below threshold | Balance drops below $5 | | `credits.exhausted` | Credit balance is $0 | Balance reaches $0 | + + `classification.failed` fires on every failure path, including provider timeouts, rate limit errors from upstream AI providers, and unexpected internal errors. The comment's `processing_status` is always reset to `failed` so it can be retried. There is no scenario where a comment stays stuck in `processing` state. + + ## Webhook payload +### classification.completed + ```json { "id": "evt_abc123", @@ -34,6 +40,22 @@ Receive real-time notifications when events occur in your NAWA account. Webhooks } ``` +### classification.failed + +```json +{ + "id": "evt_fail789", + "type": "classification.failed", + "created_at": "2025-01-15T12:01:00Z", + "data": { + "request_id": "req_ghi012", + "comment_id": "cmt_abc123", + "error_message": "AI provider temporarily unavailable.", + "processing_status": "failed" + } +} +``` + ## Webhook signing secret Your webhook signing secret starts with `nawa_wh_` and is generated when you register a webhook endpoint. Store it securely - it's shown only once.