GET /v1/status
Check the progress and results of a book generation job.
Overview
After starting a generation with POST /v1/book, use this endpoint to poll for progress and retrieve results. The endpoint returns the current status, progress percentage and, when complete, the download URL.
Endpoint
GET https://api.nelliewriter.com/v1/status/{requestId}
Authentication
Not required. This is a public endpoint. Anyone with the requestId can check status.
đź’ˇ Tip: Request IDs are UUIDs and effectively temporary passwords, providing security through obscurity.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
requestId | string | The job ID returned by POST /v1/book |
Example Requests
cURL
curl https://api.nelliewriter.com/v1/status/abcd1234-ef56-7890-abcd-12ef34567890
Python SDK
from nellie_api import Nellie
client = Nellie(api_key="nel_your_api_key")
status = client.books.retrieve("abcd1234-ef56-7890-abcd-12ef34567890")
print(f"Status: {status.status}")
print(f"Progress: {status.progress}%")
if status.is_successful():
print(f"Download: {status.result_url}")
Python (requests)
import requests
request_id = "abcd1234-ef56-7890-abcd-12ef34567890"
response = requests.get(f"https://api.nelliewriter.com/v1/status/{request_id}")
data = response.json()
print(f"Status: {data['status']} ({data['progress']}%)")
Response
Queued
Job is waiting in the queue:
{
"requestId": "abcd1234-ef56-7890-abcd-12ef34567890",
"status": "queued",
"progress": 0,
"messages": [
"Request received, waiting in queue..."
],
"createdAt": "2025-12-03T10:30:00Z",
"completedAt": null,
"creditsUsed": 0
}
Processing
Job is actively generating:
{
"requestId": "abcd1234-ef56-7890-abcd-12ef34567890",
"status": "processing",
"progress": 45,
"messages": [
"Request received, starting job...",
"Generating outline...",
"Creating characters...",
"Writing Chapter 1..."
],
"createdAt": "2025-12-03T10:30:00Z",
"completedAt": null,
"creditsUsed": 0
}
Completed
Job finished successfully:
{
"requestId": "abcd1234-ef56-7890-abcd-12ef34567890",
"status": "completed",
"progress": 100,
"messages": [
"processing...",
],
"createdAt": "2025-12-03T10:30:00Z",
"completedAt": "2025-12-03T10:55:00Z",
"creditsUsed": 250,
"resultUrl": "https://api.nelliewriter.com/v1/download/abcd1234-ef56-7890-abcd-12ef34567890"
}
Failed
Job encountered an error:
{
"requestId": "abcd1234-ef56-7890-abcd-12ef34567890",
"status": "failed",
"progress": 34,
"messages": [
"processing...",
"Error: Insufficient credits"
],
"createdAt": "2025-12-03T10:30:00Z",
"completedAt": "2025-12-03T10:32:00Z",
"creditsUsed": 0,
"error": "Insufficient credits",
"errorMessage": "Insufficient credits"
}
Response Fields
| Field | Type | Description |
|---|---|---|
requestId | string | The job identifier |
status | string | Current status (see below) |
progress | integer | Completion percentage (0-100) |
messages | array | Log of loading steps |
createdAt | string | ISO 8601 timestamp when job was created |
completedAt | string | null | ISO 8601 timestamp when job finished |
creditsUsed | integer | Credits consumed |
resultUrl | string | Download URL (only when completed) |
error | string | Error description (only when failed) |
errorMessage | string | Error description (alias for error) |
Status Values
| Status | Description |
|---|---|
queued | Waiting in the generation queue |
processing | Actively generating content |
completed | Successfully finished |
failed | Generation failed |
Error Response
404 Not Found
{
"success": false,
"error": "Request not found",
"errorCode": "NOT_FOUND"
}
This occurs when:
- The
requestIdis incorrect - The
requestIddoesn’t exist - The
requestIdformat is invalid
Polling Strategy
Recommended Approach
import time
from nellie_api import Nellie
client = Nellie(api_key="nel_...")
# Start a job
book = client.books.create(prompt="A mystery novel")
# Poll every 2 minutes
while True:
status = client.books.retrieve(book.request_id)
print(f"Progress: {status.progress}%")
if status.status == "completed":
print(f"Done! Download: {status.result_url}")
break
elif status.status == "failed":
print(f"Failed: {status.error}")
break
time.sleep(120) # Wait 2 minutes
Using wait_for_completion (SDK)
The Python SDK provides a built-in polling helper:
from nellie_api import Nellie
client = Nellie(api_key="nel_...")
book = client.books.create(prompt="A mystery novel")
# Blocks until complete
result = client.books.wait_for_completion(
book.request_id,
poll_interval=120, # Check every 2 minutes (min: 60s)
timeout=7200, # Max wait: 2 hours
on_progress=lambda s: print(f"Progress: {s.progress}%")
)
if result.is_successful():
print(f"Download: {result.result_url}")
else:
print(f"Failed: {result.error}")
Polling Guidelines
| ✅ DO | ❌ DON’T |
|---|---|
| Poll every 2 minutes (120s) | Poll faster than every 60 seconds |
| Use webhooks when possible | Busy-loop without delays |
| Handle timeouts gracefully | Assume jobs complete quickly |
| Log progress for debugging | Ignore the messages array |
Using the Result URL
The resultUrl is a signed URL that:
- Generates a fresh signed download link on each request (valid for 1 hour)
- Can be downloaded directly via HTTP GET
# Download the generated book
curl -L -o my_book.pdf "https://api.nelliewriter.com/v1/download/abcd1234-ef56-7890-abcd-12ef34567890"
import requests
response = requests.get(result.result_url)
with open("my_book.pdf", "wb") as f:
f.write(response.content)
Webhooks Alternative
Instead of polling, provide a webhook_url when creating the job to receive a POST notification when it completes:
book = client.books.create(
prompt="A mystery novel",
webhook_url="https://myapp.com/webhooks/nellie"
)
# No need to poll; you'll receive a webhook when done
See Webhooks for details.
Related Endpoints
- POST /v1/book: Start a generation job
- GET /v1/usage: View credit history
See Also
- Webhooks: Receive push notifications instead of polling
- Rate Limits: Understand polling limits
- Troubleshooting: Debug failed jobs