Async Jobs
How to use asynchronous processing and poll for job results.
Overview
The Humanizer, AI Detector, and Detect & Humanize endpoints support asynchronous processing. Instead of waiting for the result in the response, you receive a task_id and can either:
- Poll for the result via
GET /api/jobs/{task_id}/ - Receive a webhook at your
callback_url - Both — poll and receive a webhook
Submitting an Async Request
Add poll: true and/or callback_url to any supported endpoint:
curl -X POST https://developer-portal.walterwrites.ai/api/humanizer/ \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{
"content": "Your text here...",
"poll": true
}'Response (202 Accepted):
{
"status": "pending",
"task_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"result": null,
"word_count": 256,
"credits_remaining": 1744,
"user": {
"id": 12345
}
}Credits are consumed when the job is accepted.
GET /api/jobs/{task_id}/
Retrieve the status and result of an async job.
Authentication: X-API-Key header
Request
curl https://developer-portal.walterwrites.ai/api/jobs/a1b2c3d4-e5f6-7890-abcd-ef1234567890/ \
-H "X-API-Key: YOUR_API_KEY"Response — Processing
The job is still running:
{
"status": "processing",
"task_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"result": null,
"service_name": null,
"execution_time": null,
"word_count": null,
"credits_remaining": null,
"user": {
"id": 12345
}
}Response — Success
The job completed successfully. The response structure matches the synchronous response of the endpoint that created the job (humanizer, detector, or detect-and-humanize).
Humanizer job example:
{
"status": "success",
"task_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"result": "Humanized text content...",
"service_name": "humanizer_service",
"execution_time": 3.21,
"word_count": 256,
"credits_remaining": 1744,
"user": {
"id": 12345
}
}Detector job example:
{
"status": "success",
"task_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"result": "ai",
"ai_score": 0.87,
"items": [...],
"service_name": "detector_service",
"execution_time": 1.52,
"word_count": 256,
"credits_remaining": 1744,
"user": {
"id": 12345
}
}Response — Failed
The job failed (credits are refunded automatically):
{
"status": "failed",
"task_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"result": null,
"error": "Processing failed.",
"word_count": 256
}Job Status Values
| Status | Meaning |
|---|---|
processing | Job is queued or running — poll again shortly |
success | Job completed — result contains the output |
failed | Job failed — credits were refunded automatically |
Important Notes
- Results expire after 1 hour. After that, the endpoint returns
404. - Only the owner of the job can retrieve the result. Using another user's
task_idreturns404. - Concurrent job limit — The number of pending async jobs you can have at once depends on your plan. If exceeded, new async requests are rejected with
429 Too Many Requests.
| Plan | Pending Job Limit |
|---|---|
| Trial | 2 |
| 300K | 5 |
| 1M | 10 |
| 2M | 15 |
| 5M | 20 |
| 12M | 30 |
| 25M | 50 |
Polling Strategy
We recommend polling with exponential backoff:
1st poll: after 2 seconds
2nd poll: after 4 seconds
3rd poll: after 8 seconds
...and so on, up to a maximum of 30 seconds between pollsWebhook Delivery
When using callback_url, the result is POSTed to your URL once the job completes. The payload is the same JSON structure as the polling response.
If you also provided a webhook_secret, it is included in the X-Webhook-Secret header so you can verify the request authenticity.
Webhook delivery is retried up to 3 times with exponential backoff if your server returns an error.
The callback_url must be a publicly routable URL. Requests to private, internal, or reserved IP addresses are blocked for security reasons.