One prompt. A finished book.

Open Nellie Sign in

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

ParameterTypeDescription
requestIdstringThe 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

FieldTypeDescription
requestIdstringThe job identifier
statusstringCurrent status (see below)
progressintegerCompletion percentage (0-100)
messagesarrayLog of loading steps
createdAtstringISO 8601 timestamp when job was created
completedAtstring | nullISO 8601 timestamp when job finished
creditsUsedintegerCredits consumed
resultUrlstringDownload URL (only when completed)
errorstringError description (only when failed)
errorMessagestringError description (alias for error)

Status Values

StatusDescription
queuedWaiting in the generation queue
processingActively generating content
completedSuccessfully finished
failedGeneration failed

Error Response

404 Not Found

{
  "success": false,
  "error": "Request not found",
  "errorCode": "NOT_FOUND"
}

This occurs when:

  • The requestId is incorrect
  • The requestId doesn’t exist
  • The requestId format is invalid

Polling Strategy

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 possibleBusy-loop without delays
Handle timeouts gracefullyAssume jobs complete quickly
Log progress for debuggingIgnore 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.

See Also