API contract summary
Base URL: https://akonibooks.com/api/agent/v1. Every request must carry
your key in the X-Agent-Key header. All request and response bodies are
JSON. Errors always take the shape {"error": {"code": "...", "message": "..."}}.
GET /api/agent/v1/catalog
X-Agent-Key: <your key> Endpoints
GET /catalog
Products, prices, styles, themes, bilingual languages, age range, policies, and rate limits.
Response
{
"products": [
{ "id": "digital", "price_usd": 9.99, "includes_pdf": true, "ships": false },
{ "id": "softcover", "price_usd": 29.99, "includes_pdf": true, "ships": true, "shipping": "5-7 business days" },
{ "id": "hardcover", "price_usd": 39.99, "includes_pdf": true, "ships": true, "shipping": "5-7 business days" }
],
"styles": [ { "slug": "whimsical-watercolor", "name": "Whimsical Watercolor" }, ... ],
"themes": [ { "slug": "adventure", "name": "Adventure" }, ... ],
"bilingual_languages": ["es", "fr", "pt", "zh"],
"age_range": { "min": 2, "max": 10 },
"policies": {
"preview": "free",
"timing": "in minutes",
"guarantee": "...",
"photo_consent_text": "...",
"privacy_url": "https://akonibooks.com/privacy",
"terms_url": "https://akonibooks.com/terms"
},
"limits": { "previews_per_email_per_day": 15 }
} POST /previews
Generate a free preview of a personalized book. Starts async generation; poll GET /books/{book_id} for status.
Request body
{
"parent_email": "parent@example.com",
"child": { "name": "Maya", "age": 6, "pronouns": "she/her", "interests": ["dinosaurs"] },
"theme": "adventure",
"art_style": "whimsical-watercolor",
"bilingual_language": "es",
"dedication_from": "Grandma Sue",
"character": { "method": "avatar", "avatar_id": "avatar-3" },
"photo_consent": false,
"agent_user_ref": "your-internal-user-id"
} Response
// 202 Accepted
{
"book_id": "maya-abc123",
"status": "generating",
"status_url": "/api/agent/v1/books/maya-abc123",
"preview_url": "https://akonibooks.com/preview/maya-abc123",
"eta": "minutes"
}
// 400 validation error, or 429 { "error": { "code": "preview_cap" } } GET /books/{book_id}?parent_email=
Check a book's generation status, or its paid/print status after purchase.
Response
{
"book_id": "maya-abc123",
"status": "ready",
"title": "Maya and the Lost Valley",
"preview_url": "https://akonibooks.com/preview/maya-abc123",
"pages_ready": 16,
"pages_total": 16,
"paid": false,
"product_type_paid": null,
"print_status": null,
"products": [
{ "id": "digital", "price_usd": 9.99 },
{ "id": "softcover", "price_usd": 29.99 },
{ "id": "hardcover", "price_usd": 39.99 }
]
}
// 404 if book_id doesn't belong to parent_email POST /books/{book_id}/orders
Buy a previewed book as a digital PDF, softcover, or hardcover.
Request body
{
"product": "hardcover",
"parent_email": "parent@example.com",
"shipping_address": {
"first_name": "Ama", "last_name": "Owusu",
"address1": "1 Main St", "address2": null,
"city": "Austin", "state": "TX", "zip": "78701",
"country": "US", "phone": null
},
"payment": { "mode": "checkout_link" }
} Response
// 201 Created (checkout_link mode)
{
"checkout_url": "https://checkout.stripe.com/pay/xyz",
"expires_at": "2026-09-20T00:00:00Z",
"amount_usd": 39.99,
"product": "hardcover"
}
// 409 { "error": { "code": "already_paid" } }
// 501 { "error": { "code": "delegated_payments_disabled" } } for mode: "delegated" POST /books/{book_id}/reorders
Order another printed copy of an already-paid book, shipped to a new address. A human reviews it before it prints.
Request body
{
"product": "softcover",
"parent_email": "parent@example.com",
"shipping_address": { "...": "same shape as /orders" },
"payment": { "mode": "checkout_link" }
} Response
// Same response shapes as POST /books/{book_id}/orders The consent rule
An agent may only submit character.method: "photo" together with
"photo_consent": true after the parent or guardian it's talking to has
explicitly consented, in that conversation, to their child's photo
being used to generate the storybook character. GET /catalog returns the
exact, current wording to show them first, as
policies.photo_consent_text — always relay that text rather than
paraphrasing it. Never infer consent from a photo URL being supplied, from silence,
or from a previous session. If consent hasn't been given, use
character.method: "avatar" or "description" instead —
neither needs photo consent.
The payment rule
Phase 1 (current): every purchase and reorder call returns a Stripe
checkout_url. The agent must hand that link to the human and let them
pay themselves, in their own browser — the API never accepts card details from an
agent, and an agent should never ask the human for one.
Delegated payment ("payment": { "mode": "delegated", "provider": "stripe", "payment_method": ... })
exists in the contract but is gated behind a feature flag and not open yet
— calling it today returns 501 delegated_payments_disabled. Don't build
against it as your primary path.
Rate limits
Free previews are capped at 15 per parent email per day. Exceeding it
returns 429 { "error": { "code": "preview_cap" } }. There is no
separate cap on GET /catalog, GET /books/{book_id}, or
order/reorder calls beyond normal abuse protection.
Getting a key
Email hello@akonibooks.com with your agent
or product name and expected volume to request an X-Agent-Key.
MCP server
For agent runtimes that speak MCP (Model Context Protocol) directly — Claude Code,
Claude Desktop, and compatible clients — Akoni Books ships a stdio MCP server that
wraps this same API as five tools: akoni_catalog,
akoni_create_preview, akoni_get_book,
akoni_order_book, and akoni_reorder_print. It enforces the
consent rule above in code — it refuses a photo-based preview unless
photo_consent=True — and never collects payment details.
Claude Code
claude mcp add akoni-books \
-e AKONI_AGENT_KEY=your-key-here \
-- /path/to/agent/mcp/.venv/bin/python /path/to/agent/mcp/akoni_mcp_server.py Claude Desktop (claude_desktop_config.json)
{
"mcpServers": {
"akoni-books": {
"command": "/path/to/agent/mcp/.venv/bin/python",
"args": ["/path/to/agent/mcp/akoni_mcp_server.py"],
"env": { "AKONI_AGENT_KEY": "your-key-here" }
}
}
}
Full install steps, environment variables, and an example transcript: see
agent/mcp/README.md in the Akoni Books app repository.