Troubleshooting #
Step-by-step guides for debugging common Nellie API issues.
Quick Diagnosis #
Is the API Accessible? #
# Test API connectivity
curl -I https://api.nelliewriter.com/v1/configuration
Expected: HTTP/2 200
Is Your Key Valid? #
# Test authentication
curl https://api.nelliewriter.com/v1/usage
-H "X-API-Key: nel_your_key"
Expected: JSON response with usage data
Is Your Request Valid? #
# Test with minimal request
curl -X POST https://api.nelliewriter.com/v1/book
-H "X-API-Key: nel_your_key"
-H "Content-Type: application/json"
-d '{}'
Expected: 202 Accepted with requestId
Authentication Issues #
“Unauthorized” Error #
Symptoms:
{
"success": false,
"error": "Unauthorized",
"errorCode": "AUTH_REQUIRED"
}
Diagnosis:
- Check header name:
# Correct
-H "X-API-Key: nel_..."
# Wrong
-H "Authorization: Bearer nel_..."
-H "Api-Key: nel_..."
- Check key format:
# Valid format
nel_abc123def456ghi789...
# Invalid
abc123... # Missing prefix
- Check environment variable:
echo $NELLIE_API_KEY
# Should output your key
Solutions:
# Debug authentication
import os
api_key = os.environ.get("NELLIE_API_KEY")
# Check if set
if not api_key:
print("❌ NELLIE_API_KEY not set")
elif not api_key.startswith("nel_"):
print("❌ Invalid key format (should start with 'nel_')")
else:
print(f"✅ Key found: {api_key[:10]}...{api_key[-4:]}")
“Invalid API Key” Error #
Symptoms:
{
"success": false,
"error": "Invalid API key",
"errorCode": "AUTH_FAILED"
}
Causes:
- Key was revoked
- Key was copied incorrectly
- Using wrong environment’s key
Solution:
- Log into the Nellie dashboard
- Go to Settings → API Management
- Check if your key is listed and active
- If not, create a new key
Rate Limit Issues #
“Rate limit exceeded” Error #
Symptoms:
{
"success": false,
"error": "Rate limit exceeded: Please wait a few seconds between requests",
"errorCode": "RATE_LIMIT_EXCEEDED"
}
Diagnosis:
# Check your request timing
import time
start = time.time()
# ... your code ...
elapsed = time.time() - start
print(f"Time since last request: {elapsed}s")
# Should be > 6 seconds
Solutions:
- Add delays between requests:
import time
for prompt in prompts:
book = client.books.create(prompt=prompt)
time.sleep(7) # Wait 7 seconds between requests
- Implement retry with backoff:
from nellie_api import RateLimitError
import time
def create_with_retry(prompt):
for attempt in range(3):
try:
return client.books.create(prompt=prompt)
except RateLimitError:
wait = 6 * (attempt + 1)
print(f"Rate limited. Waiting {wait}s...")
time.sleep(wait)
raise Exception("Max retries exceeded")
“Daily rate limit exceeded” Error #
Symptoms:
{
"success": false,
"error": "Daily rate limit exceeded (15 requests/day)",
"errorCode": "RATE_LIMIT_EXCEEDED"
}
Diagnosis:
usage = client.get_usage()
print(f"Total requests today: {usage.total_requests}")
# If >= 15, you've hit the limit
Solutions:
- Wait 24 hours from your first request of the day
- Contact sales for higher limits
- Use multiple API keys (with separate accounts)
Generation Failures #
Job Status “failed” #
Symptoms:
{
"requestId": "...",
"status": "failed",
"error": "Error message here"
}
Diagnosis:
status = client.books.retrieve(request_id)
print(f"Status: {status.status}")
print(f"Progress: {status.progress}%")
print(f"Error: {status.error}")
print(f"Messages: {status.messages}")
Common Errors:
| Error | Cause | Solution |
|---|---|---|
| “Insufficient credits” | Not enough credits | Purchase more credits |
| “Content policy violation” | Inappropriate prompt | Modify your prompt |
| “Generation timeout” | Job took too long | Retry with simpler prompt |
| “Internal error” | Server issue | Retry after a few minutes |
“Insufficient credits” Error #
Diagnosis:
usage = client.get_usage()
models = client.get_models()
print(f"Credits used: {usage.total_credits_used}")
# Check cost for your model
for model in models:
print(f"{model.name}: {model.cost_per_book} credits")
Solution:
- Purchase more credits in the Nellie app
- Use a lower-cost model (2.0 instead of 3.0)
- Disable images to reduce cost
Job Stuck at 0% #
Symptoms:
- Status stays “queued” for extended time
- Progress stays at 0%
Diagnosis:
import time
status = client.books.retrieve(request_id)
print(f"Created: {status.created_at}")
print(f"Status: {status.status}")
# Check how long it's been
from datetime import datetime
created = datetime.fromisoformat(status.created_at.replace('Z', '+00:00'))
elapsed = datetime.now(created.tzinfo) - created
print(f"Elapsed: {elapsed}")
Solutions:
- Wait longer (generation can take 15-80 minutes)
- Check system status for outages
- If > 2 hours, contact support with
requestId
Webhook Issues #
Webhooks Not Received #
Diagnosis Checklist:
- Is your URL publicly accessible?
curl -X POST https://your-webhook-url.com/path
-H "Content-Type: application/json"
-d '{"test": true}'
- Is it HTTPS?
- Must be
https://(nothttp://)
- Check server logs:
- Look for incoming POST requests
- Check for any errors
- Is the certificate valid?
curl -v https://your-webhook-url.com 2>&1 | grep "SSL certificate"
Solutions:
- Use a tunnel for local testing:
ngrok http 5000
# Then use the https://xxx.ngrok.io URL
- Check firewall allows incoming connections
- Ensure your server responds within 30 seconds
WebhookSignatureErrorraised- Signature comparison fails
Signature Verification Fails #
Symptoms:
Diagnosis:
# Debug signature verification
sig_header = request.headers.get("X-Nellie-Signature")
print(f"Header: {sig_header}")
# Parse components
parts = dict(x.split('=', 1) for x in sig_header.split(','))
print(f"Timestamp: {parts.get('t')}")
print(f"Signature: {parts.get('v1')}")
# Check timestamp age
import time
timestamp = int(parts.get('t', 0))
age = abs(time.time() - timestamp)
print(f"Signature age: {age}s (max allowed: 300s)")
Common Causes:
- Wrong secret:
- Make sure you’re using the webhook secret (starts with
whsec_) - Not the API key
- Modified payload:
- Use raw request body, not parsed JSON
# ✅ Correct
payload = request.data # Raw bytes
# ❌ Wrong
payload = json.dumps(request.json) # Re-serialized
- Timestamp expired:
- Signature must be within 5 minutes
- Check server time sync
Solution:
from nellie_api import Webhook, WebhookSignatureError
@app.route("/webhook", methods=["POST"])
def webhook():
# Use raw body
payload = request.data
sig_header = request.headers.get("X-Nellie-Signature")
# Debug info
print(f"Payload length: {len(payload)}")
print(f"Signature header: {sig_header}")
try:
event = Webhook.construct_event(payload, sig_header, WEBHOOK_SECRET)
return "OK", 200
except WebhookSignatureError as e:
print(f"Verification failed: {e}")
return "Invalid signature", 400
SDK Issues #
Import Errors #
Symptoms:
ModuleNotFoundError: No module named 'nellie_api'
Solutions:
- Install the package:
pip install nellie-api
- Check virtual environment:
which python
pip list | grep nellie
- Check Python version (requires 3.8+):
python --version
Connection Errors #
Symptoms:
APIError: Connection error: ...
Diagnosis:
import requests
try:
response = requests.get("https://api.nelliewriter.com/v1/configuration", timeout=10)
print(f"Status: {response.status_code}")
except requests.exceptions.RequestException as e:
print(f"Connection error: {e}")
Solutions:
- Check internet connectivity
- Check firewall/proxy settings
- Try increasing timeout:
client = Nellie(api_key="...", timeout=60)
Timeout Errors #
Symptoms:
TimeoutError: Book generation timed out after Xs
Solutions:
- Increase timeout:
result = client.books.wait_for_completion(
request_id,
timeout=14400 # 4 hours
)
- Use webhooks instead of polling
- Check job status manually:
status = client.books.retrieve(request_id)
print(f"Status: {status.status}, Progress: {status.progress}%")
Debugging Tools #
Request Logger #
import logging
# Enable debug logging
logging.basicConfig(level=logging.DEBUG)
# Or specifically for requests
logging.getLogger("urllib3").setLevel(logging.DEBUG)
API Tester Script #
#!/usr/bin/env python3
""Test Nellie API connectivity and authentication.""
import os
import sys
from nellie_api import Nellie, NellieError
def main():
print("=" * 50)
print("NELLIE API DIAGNOSTIC")
print("=" * 50)
# Check environment
api_key = os.environ.get("NELLIE_API_KEY")
if not api_key:
print("❌ NELLIE_API_KEY not set")
sys.exit(1)
print(f"✅ API key found: {api_key[:10]}...{api_key[-4:]}")
try:
client = Nellie(api_key=api_key)
# Test configuration endpoint
print("nTesting /v1/configuration...")
config = client.get_configuration()
print(f"✅ Got {len(config.styles)} styles, {len(config.types)} types")
# Test authenticated endpoint
print("nTesting /v1/usage...")
usage = client.get_usage()
print(f"✅ Total requests: {usage.total_requests}")
print(f"✅ Credits used: {usage.total_credits_used}")
# Test models
print("nTesting /v1/models...")
models = client.get_models()
for m in models:
print(f" {m.name}: {m.cost_per_book} credits")
print("n" + "=" * 50)
print("ALL TESTS PASSED ✅")
print("=" * 50)
except NellieError as e:
print(f"n❌ Error: {e}")
sys.exit(1)
if __name__ == "__main__":
main()
Webhook Tester #
#!/usr/bin/env python3
""Test webhook signature verification.""
import json
from nellie_api import Webhook
# Test payload
payload = json.dumps({
"requestId": "test-123",
"status": "completed",
"resultUrl": "https://example.com/test.pdf"
})
# Generate signature
secret = "whsec_test_secret"
signature = Webhook.generate_signature(payload, secret)
print(f"Payload: {payload}")
print(f"Signature: {signature}")
# Verify
is_valid = Webhook.verify_signature(payload, signature, secret)
print(f"Verification: {'✅ Valid' if is_valid else '❌ Invalid'}")
Getting Help #
Information to Include #
When contacting support, include:
- Request ID (if applicable)
- Error message (full JSON response)
- Timestamp of the issue
- Code snippet (without API keys!)
- SDK version:
import nellie_api
print(nellie_api.__version__)
Support Channels #
- Email: support@buzzleco.com
- Documentation: https://nelliewriter.com/docs
- Errors — Error code reference
- Rate Limits — Understanding limits
- Webhooks — Webhook setup
- FAQ — Common questions