{"service": "teneo-agent-book-generation", "version": "2026-05-25", "summary": "Generate a complete, publish-ready non-fiction book (full manuscript + cover + PDF/EPUB/DOCX) from a topic or spec. Asynchronous: submit, poll, download.", "openapi": "https://teneo.io/openapi/agent-book-generation.yaml", "docs": "https://teneo.io/llms.txt", "agentPage": "https://teneo.io/agents", "registries": {"mcp": {"npm": "teneo-book-mcp", "npmUrl": "https://www.npmjs.com/package/teneo-book-mcp", "install": "npx -y teneo-book-mcp", "config": {"mcpServers": {"teneo-book": {"command": "npx", "args": ["-y", "teneo-book-mcp"], "env": {"TENEO_API_KEY": "tk_live_..."}}}}}, "skill": {"install": "npx skills add https://teneo.io", "index": "https://teneo.io/.well-known/skills/index.json", "name": "teneo-book-generation"}, "plugin": "https://teneo.io/.well-known/ai-plugin.json"}, "auth": {"methods": ["teneo-auth-agent-token", "bearer-api-key", "x-service-key"], "howTo": "Preferred external-agent flow: register through TENEO Auth auth.md, have the user approve the claim, then send the delegated agent access token as 'Authorization: Bearer <token>'. The delegated user is charged; on_behalf_of is ignored for delegated tokens. Legacy dashboard keys still work as 'Authorization: Bearer tk_...'. Ecosystem agents may send 'x-service-key' plus 'on_behalf_of': <teneo user id>.", "authMd": "https://auth.teneo.io/auth.md", "requiredScopes": {"generate": ["books.generate", "credits.spend"], "status": ["books.status"], "tools": {"outline": ["books.quote"], "cover": ["books.generate", "credits.spend"], "evaluate": ["books.status"], "niche": ["books.quote"]}}}, "pricing": {"currency": "teneo_credits", "unit": {"name": "Teneo credit", "usd": {"1": {"packPriceUsd": "69.00", "usdPerCredit": "69.00"}, "3": {"packPriceUsd": "177.00", "usdPerCredit": "59.00"}, "10": {"packPriceUsd": "449.00", "usdPerCredit": "44.90"}}, "listUsdPerCredit": "69.00", "note": "Credits never expire. Buy at https://teneo.io/pricing."}, "formula": "requiredCredits = bookCredits + coverCredits + qualityCreditsReserve, where bookCredits = wordBandCredits(estimatedWordCount) * modelMultiplier(model_version), estimatedWordCount = number_of_chapters * topics_per_chapter * subtopic_count * 350 (defaults 12 / 3 / 3, clamped to 3-24 / 1-6 / 1-5), coverCredits is a flat charge, and qualityCreditsReserve applies only when the caller sets min_eval_score. Credits are rounded to 2 decimal places.", "wordBandCredits": [{"maxEstimatedWords": 25000, "credits": "0.8"}, {"maxEstimatedWords": 35000, "credits": "0.9"}, {"maxEstimatedWords": 60000, "credits": "1.0"}, {"maxEstimatedWords": 70000, "credits": "1.1"}, {"maxEstimatedWords": 85000, "credits": "1.2"}, {"maxEstimatedWords": 105000, "credits": "1.3"}, {"maxEstimatedWords": null, "credits": "1.5", "note": "above the last band"}], "modelMultipliers": {"claude-fable-5": "4.0", "claude-haiku-4-5": "0.22", "claude-opus-4-6": "2.0", "claude-opus-4-7": "2.0", "claude-opus-4-8": "2.0", "claude-opus-5": "2.0", "claude-sonnet-4-6": "1.0", "claude-sonnet-5": "1.0", "deepseek-v3.2": "0.08", "deepseek-v4-pro": "0.15", "gemini-2.5-flash": "0.08", "gemini-3-flash-preview": "0.12", "gemini-3.1-flash-lite-preview": "0.10", "gemini-3.1-pro-preview": "0.75", "glm-5.2": "0.10", "gpt-4.1": "1.0", "gpt-4.1-2025-04-14": "1.0", "gpt-5.1-2025-11-13": "1.0", "gpt-5.2-2025-12-11": "1.0", "gpt-5.4": "1.0", "gpt-5.4-mini": "0.10", "gpt-5.5": "2.0", "gpt-5.5-pro": "6.0", "gpt-5.6-luna": "0.08", "gpt-5.6-terra": "1.0", "grok-4-fast-reasoning": "0.04", "grok-4.20-beta-0309-reasoning": "1.0", "grok-4.3": "0.22", "llama-3.3-70b": "0.06", "llama-4-maverick": "0.08", "qwen3-235b": "0.05"}, "modelMultipliersNote": "This is the price table, not an availability list \u2014 a model_version appearing here is priced here, but availability varies by environment and some entries are still in bakeoff. An unrecognised model_version prices at 1.0. Omit model_version to get defaultModel, which is always available.", "defaultModel": "gpt-4.1-2025-04-14", "coverCredits": "0.05", "qualityCreditsReserve": "0.10", "toolCredits": {"outline": "0", "niche": "0", "cover": "0.05", "evaluate": "0.10-0.40 per evaluation round"}, "toolNote": "outline and niche are free to call (rate-limited: 30 outlines per user per UTC day) so an agent can validate direction before committing to a paid generation. Try one of those first.", "workedExample": {"request": "the default request shape below, unchanged", "estimatedWordCount": 37800, "model": "gpt-4.1-2025-04-14", "bookCredits": "1.00", "coverCredits": "0.05", "requiredCredits": "1.05", "approxUsdAtListPrice": "72.45"}, "quote": "POST /api/agent/books/generate always prices the request before it charges. If the account cannot cover it the call returns 402 with the full quote in the body and nothing is charged, so a 402 is a safe way to read the exact price. A funded call returns 202 with the same quote object.", "settlement": "Charged against the caller's Teneo credit balance during the workflow, idempotent by generationId (a replayed request replays the original debit rather than charging twice), and refunded in full if generation fails. Finalization is included.", "accountRequired": true, "accountRequiredNote": "A funded Teneo credit balance must exist before the first paid call. There is no pay-per-call, L402, or machine-payments endpoint yet, so an agent with a budget but no Teneo account cannot transact. The free outline and niche tools are the only calls available without a balance.", "topUpUrl": "https://teneo.io/pricing"}, "endpoints": {"capabilities": "GET /api/agent/capabilities", "generate": "POST /api/agent/books/generate", "status": "GET /api/agent/books/status/{jobId}"}, "async": {"pattern": "POST generate -> 202 {jobId, pollUrl, estimatedMinutes} -> poll status until status=='completed' -> download from outputManifest. Optionally pass 'callback_url' for a completion webhook.", "estimatedMinutes": 45}, "request": {"required": {"title": "string - book title (aliases: book_topic, topic)", "description": "string - what the book covers (alias: desired_outcome)", "target_audience": "string - who it is for"}, "optional": {"creative_direction": "string - tone / style / angle", "number_of_chapters": "int 3-24 (default 12)", "topics_per_chapter": "int 1-6 (default 3)", "subtopic_count": "int 1-5 (default 3)", "model_version": "string (default gpt-4.1-2025-04-14)", "book_type": "'nonfiction' (default); fiction is not in v1", "author_name": "string - attribution", "output_formats": "array of 'pdf' | 'epub' | 'docx' (default all three)", "callback_url": "string - webhook POSTed on completion", "on_behalf_of": "string - teneo user id to charge (required with x-service-key)", "min_eval_score": "number 0-10 quality floor. OMITTED (default): the book is evaluated against the platform default floor (8.0) in OBSERVE mode - platform-billed, no extra charges, never fails the job; the receipt records gateDecision 'below_floor_observed' when the score misses. SET EXPLICITLY: ENFORCED mode - evaluate -> rewrite weak sections -> re-evaluate until the score clears the floor, then finalize. Adds evaluation (~0.1-0.4 credits/round) + rewrite (~0.01/section) charges; the job fails with a FULL refund if the floor cannot be met. Set 0 to opt out of evaluation entirely. Result carries an outputManifest.quality receipt {evalScore, evalThreshold, rewriteRounds, contentVersion, gateDecision, routerReceipt}. routerReceipt is the machine-readable next-action router for delivery, deeper eval, rewrite, panel proof, and publish-packet eligibility.", "max_rewrite_rounds": "int 0-3 (default 2) - rewrite budget under min_eval_score", "evaluation_mode": "'pro' (default) | 'core' - evaluation tier for the quality floor", "rewrite_product": "'core_rewrite' (default) | 'pro_rewrite' - rewrite tier", "publish_account": "string - KDP account slug (e.g. 'teneo-publishing'). With min_eval_score set, a completed book also emits a Publish Packet (publish-packets/{account}/{bookId}/packet.json) for the KDP draft pipeline. Omit to skip packet emission."}}, "example": {"headers": {"x-service-key": "<your key>"}, "body": {"title": "The Indie Author's KDP Launch Playbook", "description": "A practical launch system for self-published nonfiction on Amazon KDP.", "target_audience": "self-publishing nonfiction authors", "number_of_chapters": 10, "output_formats": ["pdf", "epub"], "on_behalf_of": "<teneo-user-id>"}}, "workflow": ["outline_candidates", "outline_selection", "book_generation", "quality_evaluation (always - observe-mode on the default floor, enforced when caller sets min_eval_score; opt out with 0)", "quality_rewrite (enforced floors only, below the floor, up to max_rewrite_rounds)", "cover_generation", "finalization"], "output": {"shape": "when status=='completed': outputManifest = { coverUrl, formats: {pdf:{url}, epub:{url}, docx:{url}}, fullBookId, contentVersion, quality? {evalScore, evalThreshold, rewriteRounds, contentVersion, gateDecision, gatedAt, routerReceipt} }", "note": "Format download URLs are time-limited (~1 hour); fetch promptly."}, "useCases": ["Generate a complete non-fiction book (manuscript + cover + PDF/EPUB/DOCX) from a topic or spec", "Turn a user's expertise, notes, or research into a KDP-ready manuscript", "Produce a structured outline plus full chapters (not just an outline)", "Give an agent a finished, downloadable book to hand back to its user"], "useCasesRoadmap": ["additional granular tools beyond outline / cover / evaluate / niche"], "tools": {"outline": "POST /api/agent/tools/outline", "cover": "POST /api/agent/tools/cover", "evaluate": "POST /api/agent/tools/evaluate", "niche": "POST /api/agent/tools/niche"}, "fit": {"good": ["complete non-fiction books from a topic or niche", "KDP-ready files for self-publishing", "an agent producing a long-form book for its user"], "notFor": ["a single short answer", "fiction or novels (v1)"]}, "statusEndpoint": "/api/agent/books/status/{jobId}"}