{"openapi":"3.1.0","info":{"title":"papergarden API","version":"0.1.0","description":"Make printed picture books. Same operations as the MCP server at /mcp. The bookId is the edit key. Read GET /api/v1/guide first. Errors: HTTP status + {error: {code, message, fix, path?, retryable}}."},"servers":[{"url":"https://papergarden.ai/api/v1"}],"paths":{"/guide":{"get":{"operationId":"get_guide","summary":"Get the book-making guide","description":"How to make a papergarden book: workflow, page geometry (630x630pt, safe area 45..585), images, text and taste rules. Read topic \"all\" once before making a book.","parameters":[{"name":"topic","in":"query","required":false,"description":"Which part. Default \"all\".","schema":{"type":"string","enum":["all","workflow","geometry","images","text","taste","ordering"],"description":"Which part. Default \"all\"."}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"guide":{"type":"string","description":"Markdown."},"server":{"type":"object","properties":{"url":{"type":"string"},"environment":{"type":"string","description":"\"production\" or \"dev\". Dev books, orders and payments are tests."},"version":{"type":"string","description":"Deployed build. If two connections differ, trust the one whose tools match this guide."},"tools":{"type":"array","items":{"type":"string"},"description":"The tools this server has."}},"required":["url","environment","version","tools"],"additionalProperties":false}},"required":["guide","server"],"additionalProperties":false}}}},"default":{"description":"ToolError: the call did nothing. See error.fix.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_input","book_not_found","version_conflict","page_not_found","layer_not_found","asset_not_found","upload_not_found","page_limits","image_missing","image_unusable","order_not_found","order_locked","auth_required","unavailable","rate_limited","internal"]},"message":{"type":"string"},"fix":{"type":"string","description":"What to change and retry."},"path":{"type":"string","description":"Field that caused it, e.g. \"ops[3].layer.x\"."},"retryable":{"type":"boolean"},"currentVersion":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["code","message","fix","retryable"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}},"x-mcp-tool":"get_guide","x-annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":false,"idempotentHint":true}}},"/books":{"post":{"operationId":"create_book","summary":"Create a book","description":"Start a new picture book. Returns its bookId (also the edit key: keep it, don't show it in public links) and viewUrl (a read-only page to share). New books are anonymous.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":200},"pages":{"type":"integer","minimum":24,"maximum":84},"notes":{"type":"string","maxLength":20000,"description":"The plan: manuscript, palette, style sentence, characters."},"background":{"type":"string","description":"Colour as #rrggbb.","examples":["#FAF7F0"],"allOf":[{"pattern":"^#[0-9a-fA-F]{6}$","description":"Book paper colour. Default #FAF7F0 (warm off-white)."}]}},"required":["title"],"additionalProperties":false}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"bookId":{"type":"string","description":"The book id from create_book (starts with bk_). It is also the edit key: keep it private."},"version":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Book version. Starts at 1, +1 per committed edit."},"title":{"type":"string"},"pageCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"viewUrl":{"type":"string","description":"Read-only viewer. Share this with the user."},"next":{"type":"string","description":"What to do now."}},"required":["bookId","version","title","pageCount","viewUrl","next"],"additionalProperties":false}}}},"default":{"description":"ToolError: the call did nothing. See error.fix.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_input","book_not_found","version_conflict","page_not_found","layer_not_found","asset_not_found","upload_not_found","page_limits","image_missing","image_unusable","order_not_found","order_locked","auth_required","unavailable","rate_limited","internal"]},"message":{"type":"string"},"fix":{"type":"string","description":"What to change and retry."},"path":{"type":"string","description":"Field that caused it, e.g. \"ops[3].layer.x\"."},"retryable":{"type":"boolean"},"currentVersion":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["code","message","fix","retryable"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}},"x-mcp-tool":"create_book","x-annotations":{"readOnlyHint":false,"destructiveHint":false,"openWorldHint":false,"idempotentHint":false}},"get":{"operationId":"list_books","summary":"List my books","description":"The signed-in user's books across chats (needs the papergarden account connected). Anonymous books appear here once the user claims them.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"books":{"type":"array","items":{"type":"object","properties":{"bookId":{"type":"string","description":"The book id from create_book (starts with bk_). It is also the edit key: keep it private."},"title":{"type":"string"},"version":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Book version. Starts at 1, +1 per committed edit."},"pageCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"updatedAt":{"type":"string"},"viewUrl":{"type":"string"},"ordered":{"type":"boolean","description":"true = at least one paid order."}},"required":["bookId","title","version","pageCount","updatedAt","viewUrl","ordered"],"additionalProperties":false}}},"required":["books"],"additionalProperties":false}}}},"default":{"description":"ToolError: the call did nothing. See error.fix.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_input","book_not_found","version_conflict","page_not_found","layer_not_found","asset_not_found","upload_not_found","page_limits","image_missing","image_unusable","order_not_found","order_locked","auth_required","unavailable","rate_limited","internal"]},"message":{"type":"string"},"fix":{"type":"string","description":"What to change and retry."},"path":{"type":"string","description":"Field that caused it, e.g. \"ops[3].layer.x\"."},"retryable":{"type":"boolean"},"currentVersion":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["code","message","fix","retryable"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}},"x-mcp-tool":"list_books","x-annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":false,"idempotentHint":true}}},"/books/{bookId}/show":{"get":{"operationId":"show_book","summary":"Show the book","description":"Open the book in the chat as an interactive widget (pages, print status, Upload and Order buttons). Call it once after create_book so the user can watch; it refreshes itself when you edit. Other clients get the view link.","parameters":[{"name":"bookId","in":"path","required":true,"schema":{"type":"string","description":"The book id from create_book (starts with bk_). It is also the edit key: keep it private."}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"bookId":{"type":"string","description":"The book id from create_book (starts with bk_). It is also the edit key: keep it private."},"version":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Book version. Starts at 1, +1 per committed edit."},"title":{"type":"string"},"printReady":{"type":"boolean"},"viewUrl":{"type":"string","description":"The same book as a web page, for any client."}},"required":["bookId","version","title","printReady","viewUrl"],"additionalProperties":false}}}},"default":{"description":"ToolError: the call did nothing. See error.fix.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_input","book_not_found","version_conflict","page_not_found","layer_not_found","asset_not_found","upload_not_found","page_limits","image_missing","image_unusable","order_not_found","order_locked","auth_required","unavailable","rate_limited","internal"]},"message":{"type":"string"},"fix":{"type":"string","description":"What to change and retry."},"path":{"type":"string","description":"Field that caused it, e.g. \"ops[3].layer.x\"."},"retryable":{"type":"boolean"},"currentVersion":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["code","message","fix","retryable"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}},"x-mcp-tool":"show_book","x-annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":false,"idempotentHint":true}}},"/books/{bookId}":{"get":{"operationId":"get_book","summary":"Get a book","description":"The whole book (or some pages) as JSON: version, surfaces with layers, assets, print issues, printReady and the view link. Call it before editing if you don't know the current version.","parameters":[{"name":"bookId","in":"path","required":true,"schema":{"type":"string","description":"The book id from create_book (starts with bk_). It is also the edit key: keep it private."}},{"name":"pages","in":"query","required":false,"style":"form","explode":false,"description":"Surfaces to return, e.g. [\"cover\", 1, 2]. Default: all.","schema":{"type":"array","items":{"anyOf":[{"type":"string","enum":["cover"]},{"type":"integer","minimum":1,"maximum":84,"description":"1-based page number."}],"description":"\"cover\" or a 1-based page number. Page 1 is a right-hand page; spreads are 2+3, 4+5, ..."},"description":"Surfaces to return, e.g. [\"cover\", 1, 2]. Default: all."}},{"name":"include","in":"query","required":false,"style":"form","explode":false,"description":"What to include. Default: all of layers, assets, issues.","schema":{"type":"array","items":{"type":"string","enum":["layers","assets","issues"]},"description":"What to include. Default: all of layers, assets, issues."}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"bookId":{"type":"string","description":"The book id from create_book (starts with bk_). It is also the edit key: keep it private."},"version":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Book version. Starts at 1, +1 per committed edit."},"title":{"type":"string"},"notes":{"type":"string"},"background":{"type":"string","description":"Colour as #rrggbb.","examples":["#FAF7F0"],"allOf":[{"pattern":"^#[0-9a-fA-F]{6}$","description":"Book paper colour."}]},"pageCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"claimed":{"type":"boolean"},"cover":{"type":"object","properties":{"surface":{"anyOf":[{"type":"string","enum":["cover"]},{"type":"integer","minimum":1,"maximum":84,"description":"1-based page number."}],"description":"\"cover\" or a 1-based page number. Page 1 is a right-hand page; spreads are 2+3, 4+5, ..."},"background":{"type":"string","description":"Colour as #rrggbb.","examples":["#FAF7F0"],"allOf":[{"pattern":"^#[0-9a-fA-F]{6}$","description":"Effective paper colour of this surface."}]},"backgroundOverride":{"type":"boolean","description":"true = this surface has its own colour instead of the book colour."},"note":{"type":"string"},"layers":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"id":{"type":"string","description":"Layer id (starts with ly_)."},"name":{"type":"string","maxLength":80,"description":"Optional name to recognise the layer."},"x":{"type":"number","description":"Left edge in pt."},"y":{"type":"number","description":"Top edge in pt."},"width":{"type":"number","exclusiveMinimum":0,"description":"Width in pt."},"height":{"type":"number","exclusiveMinimum":0,"description":"Height in pt."},"rotation":{"type":"number","minimum":-180,"maximum":180,"description":"Degrees clockwise, around the layer centre."},"opacity":{"type":"number","minimum":0,"maximum":1,"description":"0..1."},"assetId":{"type":"string","description":"Asset id from add_image (starts with as_)."},"flipX":{"type":"boolean"},"flipY":{"type":"boolean"},"crop":{"type":"object","properties":{"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1},"w":{"type":"number","minimum":0.01,"maximum":1},"h":{"type":"number","minimum":0.01,"maximum":1}},"required":["x","y","w","h"],"additionalProperties":false,"description":"Part of the image to show, as fractions 0..1 of its width and height."},"mask":{"type":"string","enum":["none","ellipse","rounded"],"description":"Clip shape for the image."},"radius":{"type":"number","minimum":0,"description":"Corner radius in pt."},"bleed":{"type":"boolean","description":"Lets the layer run off the page. Each edge must then go past the sheet edge or stay in the safe area. Not for text."}},"required":["type","id","x","y","width","height","rotation","opacity","assetId","flipX","flipY","mask","radius","bleed"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","enum":["text"]},"id":{"type":"string","description":"Layer id (starts with ly_)."},"name":{"type":"string","maxLength":80,"description":"Optional name to recognise the layer."},"x":{"type":"number","description":"Left edge in pt."},"y":{"type":"number","description":"Top edge in pt."},"width":{"type":"number","exclusiveMinimum":0,"description":"Width in pt."},"height":{"type":"number","exclusiveMinimum":0,"description":"Height in pt."},"rotation":{"type":"number","minimum":-180,"maximum":180,"description":"Degrees clockwise, around the layer centre."},"opacity":{"type":"number","minimum":0,"maximum":1,"description":"0..1."},"fit":{"type":"boolean","description":"true = the height follows the text (height was omitted)."},"text":{"type":"string","minLength":1,"maxLength":2000,"description":"The text. Line breaks with \\n. **bold** and [word]{#hex} for a coloured word."},"font":{"type":"string","enum":["andika","nunito","quicksand","literata","fraunces","fredoka","patrick-hand"],"description":"Font id. Default andika. See get_guide topic text."},"size":{"type":"number","minimum":6,"maximum":200,"description":"Font size in pt. Default 22. Story text 18-26."},"weight":{"type":"integer","minimum":100,"maximum":900,"description":"Font weight 100-900. Default 400."},"color":{"type":"string","description":"Colour as #rrggbb.","examples":["#FAF7F0"],"pattern":"^#[0-9a-fA-F]{6}$"},"align":{"type":"string","enum":["left","center","right"]},"valign":{"type":"string","enum":["top","middle","bottom"]},"lineHeight":{"type":"number","minimum":0.8,"maximum":3,"description":"Line height as a multiple of the size. Default depends on the font."},"letterSpacing":{"type":"number","minimum":-0.1,"maximum":0.5,"description":"In em. Default 0."}},"required":["type","id","x","y","width","height","rotation","opacity","fit","text","font","size","weight","color","align","valign","lineHeight","letterSpacing"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","enum":["shape"]},"id":{"type":"string","description":"Layer id (starts with ly_)."},"name":{"type":"string","maxLength":80,"description":"Optional name to recognise the layer."},"x":{"type":"number","description":"Left edge in pt."},"y":{"type":"number","description":"Top edge in pt."},"width":{"type":"number","exclusiveMinimum":0,"description":"Width in pt."},"height":{"type":"number","exclusiveMinimum":0,"description":"Height in pt."},"rotation":{"type":"number","minimum":-180,"maximum":180,"description":"Degrees clockwise, around the layer centre."},"opacity":{"type":"number","minimum":0,"maximum":1,"description":"0..1."},"shape":{"type":"string","enum":["rect","ellipse"]},"fill":{"type":"string","description":"Colour as #rrggbb.","examples":["#FAF7F0"],"pattern":"^#[0-9a-fA-F]{6}$"},"radius":{"type":"number","minimum":0,"description":"Corner radius in pt."},"bleed":{"type":"boolean","description":"Lets the layer run off the page. Each edge must then go past the sheet edge or stay in the safe area. Not for text."}},"required":["type","id","x","y","width","height","rotation","opacity","shape","fill","radius","bleed"],"additionalProperties":false}]},"description":"Bottom first. Left out when include has no \"layers\"."}},"required":["surface","background","backgroundOverride"],"additionalProperties":false},"pages":{"type":"array","items":{"type":"object","properties":{"surface":{"anyOf":[{"type":"string","enum":["cover"]},{"type":"integer","minimum":1,"maximum":84,"description":"1-based page number."}],"description":"\"cover\" or a 1-based page number. Page 1 is a right-hand page; spreads are 2+3, 4+5, ..."},"background":{"type":"string","description":"Colour as #rrggbb.","examples":["#FAF7F0"],"allOf":[{"pattern":"^#[0-9a-fA-F]{6}$","description":"Effective paper colour of this surface."}]},"backgroundOverride":{"type":"boolean","description":"true = this surface has its own colour instead of the book colour."},"note":{"type":"string"},"layers":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"id":{"type":"string","description":"Layer id (starts with ly_)."},"name":{"type":"string","maxLength":80,"description":"Optional name to recognise the layer."},"x":{"type":"number","description":"Left edge in pt."},"y":{"type":"number","description":"Top edge in pt."},"width":{"type":"number","exclusiveMinimum":0,"description":"Width in pt."},"height":{"type":"number","exclusiveMinimum":0,"description":"Height in pt."},"rotation":{"type":"number","minimum":-180,"maximum":180,"description":"Degrees clockwise, around the layer centre."},"opacity":{"type":"number","minimum":0,"maximum":1,"description":"0..1."},"assetId":{"type":"string","description":"Asset id from add_image (starts with as_)."},"flipX":{"type":"boolean"},"flipY":{"type":"boolean"},"crop":{"type":"object","properties":{"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1},"w":{"type":"number","minimum":0.01,"maximum":1},"h":{"type":"number","minimum":0.01,"maximum":1}},"required":["x","y","w","h"],"additionalProperties":false,"description":"Part of the image to show, as fractions 0..1 of its width and height."},"mask":{"type":"string","enum":["none","ellipse","rounded"],"description":"Clip shape for the image."},"radius":{"type":"number","minimum":0,"description":"Corner radius in pt."},"bleed":{"type":"boolean","description":"Lets the layer run off the page. Each edge must then go past the sheet edge or stay in the safe area. Not for text."}},"required":["type","id","x","y","width","height","rotation","opacity","assetId","flipX","flipY","mask","radius","bleed"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","enum":["text"]},"id":{"type":"string","description":"Layer id (starts with ly_)."},"name":{"type":"string","maxLength":80,"description":"Optional name to recognise the layer."},"x":{"type":"number","description":"Left edge in pt."},"y":{"type":"number","description":"Top edge in pt."},"width":{"type":"number","exclusiveMinimum":0,"description":"Width in pt."},"height":{"type":"number","exclusiveMinimum":0,"description":"Height in pt."},"rotation":{"type":"number","minimum":-180,"maximum":180,"description":"Degrees clockwise, around the layer centre."},"opacity":{"type":"number","minimum":0,"maximum":1,"description":"0..1."},"fit":{"type":"boolean","description":"true = the height follows the text (height was omitted)."},"text":{"type":"string","minLength":1,"maxLength":2000,"description":"The text. Line breaks with \\n. **bold** and [word]{#hex} for a coloured word."},"font":{"type":"string","enum":["andika","nunito","quicksand","literata","fraunces","fredoka","patrick-hand"],"description":"Font id. Default andika. See get_guide topic text."},"size":{"type":"number","minimum":6,"maximum":200,"description":"Font size in pt. Default 22. Story text 18-26."},"weight":{"type":"integer","minimum":100,"maximum":900,"description":"Font weight 100-900. Default 400."},"color":{"type":"string","description":"Colour as #rrggbb.","examples":["#FAF7F0"],"pattern":"^#[0-9a-fA-F]{6}$"},"align":{"type":"string","enum":["left","center","right"]},"valign":{"type":"string","enum":["top","middle","bottom"]},"lineHeight":{"type":"number","minimum":0.8,"maximum":3,"description":"Line height as a multiple of the size. Default depends on the font."},"letterSpacing":{"type":"number","minimum":-0.1,"maximum":0.5,"description":"In em. Default 0."}},"required":["type","id","x","y","width","height","rotation","opacity","fit","text","font","size","weight","color","align","valign","lineHeight","letterSpacing"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","enum":["shape"]},"id":{"type":"string","description":"Layer id (starts with ly_)."},"name":{"type":"string","maxLength":80,"description":"Optional name to recognise the layer."},"x":{"type":"number","description":"Left edge in pt."},"y":{"type":"number","description":"Top edge in pt."},"width":{"type":"number","exclusiveMinimum":0,"description":"Width in pt."},"height":{"type":"number","exclusiveMinimum":0,"description":"Height in pt."},"rotation":{"type":"number","minimum":-180,"maximum":180,"description":"Degrees clockwise, around the layer centre."},"opacity":{"type":"number","minimum":0,"maximum":1,"description":"0..1."},"shape":{"type":"string","enum":["rect","ellipse"]},"fill":{"type":"string","description":"Colour as #rrggbb.","examples":["#FAF7F0"],"pattern":"^#[0-9a-fA-F]{6}$"},"radius":{"type":"number","minimum":0,"description":"Corner radius in pt."},"bleed":{"type":"boolean","description":"Lets the layer run off the page. Each edge must then go past the sheet edge or stay in the safe area. Not for text."}},"required":["type","id","x","y","width","height","rotation","opacity","shape","fill","radius","bleed"],"additionalProperties":false}]},"description":"Bottom first. Left out when include has no \"layers\"."}},"required":["surface","background","backgroundOverride"],"additionalProperties":false}},"assets":{"type":"array","items":{"type":"object","properties":{"assetId":{"type":"string","description":"Asset id from add_image (starts with as_)."},"label":{"type":"string"},"width":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Pixels."},"height":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Pixels."},"hasAlpha":{"type":"boolean","description":"true = has transparent parts (a cut-out)."},"maxWidthPt":{"type":"number","description":"Widest placement in pt that still prints sharp (240 ppi). Above 150 ppi is an error."},"idealWidthPt":{"type":"number","description":"Width in pt at 300 ppi."},"url":{"type":"string","description":"Public URL of the stored image."}},"required":["assetId","label","width","height","hasAlpha","maxWidthPt","idealWidthPt","url"],"additionalProperties":false}},"issues":{"type":"array","items":{"type":"object","properties":{"severity":{"type":"string","enum":["error","warning"],"description":"Errors block printing; warnings don't."},"code":{"type":"string","description":"e.g. outside_safe_area, text_overflow, low_resolution."},"surface":{"anyOf":[{"anyOf":[{"type":"string","enum":["cover"]},{"type":"integer","minimum":1,"maximum":84,"description":"1-based page number."}],"description":"\"cover\" or a 1-based page number. Page 1 is a right-hand page; spreads are 2+3, 4+5, ..."},{"type":"string","enum":["book"]}]},"layerId":{"type":"string","description":"Layer id (starts with ly_)."},"message":{"type":"string","description":"What is wrong, with numbers."},"fix":{"type":"string","description":"What to do."}},"required":["severity","code","surface","message","fix"],"additionalProperties":false},"description":"Print issues on the returned surfaces plus book-level ones."},"printReady":{"type":"boolean","description":"true = no blocking print errors (see readiness for finished/quality)."},"readiness":{"type":"object","properties":{"printReady":{"type":"boolean","description":"No blocking print errors. Says nothing about whether the book is finished."},"complete":{"type":"boolean","description":"No blank pages and a title on the cover."},"blankPages":{"type":"array","items":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"warnings":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Non-blocking issues, e.g. pictures below 240 ppi (print soft)."},"summary":{"type":"string","description":"One sentence for people: what's left to do."}},"required":["printReady","complete","blankPages","warnings","summary"],"additionalProperties":false,"description":"How far the book is. Done = printReady and complete, ideally with 0 warnings."},"links":{"type":"object","properties":{"view":{"type":"string"},"claim":{"type":"string","description":"For the user only: sign in there to keep the book in their account. Not for sharing."}},"required":["view"],"additionalProperties":false}},"required":["bookId","version","title","notes","background","pageCount","claimed","pages","printReady","readiness","links"],"additionalProperties":false}}}},"default":{"description":"ToolError: the call did nothing. See error.fix.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_input","book_not_found","version_conflict","page_not_found","layer_not_found","asset_not_found","upload_not_found","page_limits","image_missing","image_unusable","order_not_found","order_locked","auth_required","unavailable","rate_limited","internal"]},"message":{"type":"string"},"fix":{"type":"string","description":"What to change and retry."},"path":{"type":"string","description":"Field that caused it, e.g. \"ops[3].layer.x\"."},"retryable":{"type":"boolean"},"currentVersion":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["code","message","fix","retryable"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}},"x-mcp-tool":"get_book","x-annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":false,"idempotentHint":true}}},"/shared/{shareToken}":{"get":{"operationId":"view_book","summary":"View a shared book","description":"Read-only: the book behind a view link (/b/<shareToken>), with every surface's layers, print issues and printReady. Needs only the shareToken, never the bookId. No notes, no editing.","parameters":[{"name":"shareToken","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":100,"description":"The last part of the view link: https://papergarden.ai/b/<shareToken>."}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"version":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Book version. Starts at 1, +1 per committed edit."},"title":{"type":"string"},"background":{"type":"string","description":"Colour as #rrggbb.","examples":["#FAF7F0"],"allOf":[{"pattern":"^#[0-9a-fA-F]{6}$","description":"Book paper colour."}]},"pageCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"updatedAt":{"type":"string","description":"ISO time of the last edit."},"cover":{"type":"object","properties":{"surface":{"anyOf":[{"type":"string","enum":["cover"]},{"type":"integer","minimum":1,"maximum":84,"description":"1-based page number."}],"description":"\"cover\" or a 1-based page number. Page 1 is a right-hand page; spreads are 2+3, 4+5, ..."},"background":{"type":"string","description":"Colour as #rrggbb.","examples":["#FAF7F0"],"allOf":[{"pattern":"^#[0-9a-fA-F]{6}$","description":"Effective paper colour of this surface."}]},"backgroundOverride":{"type":"boolean","description":"true = this surface has its own colour instead of the book colour."},"note":{"type":"string"},"layers":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"id":{"type":"string","description":"Layer id (starts with ly_)."},"name":{"type":"string","maxLength":80,"description":"Optional name to recognise the layer."},"x":{"type":"number","description":"Left edge in pt."},"y":{"type":"number","description":"Top edge in pt."},"width":{"type":"number","exclusiveMinimum":0,"description":"Width in pt."},"height":{"type":"number","exclusiveMinimum":0,"description":"Height in pt."},"rotation":{"type":"number","minimum":-180,"maximum":180,"description":"Degrees clockwise, around the layer centre."},"opacity":{"type":"number","minimum":0,"maximum":1,"description":"0..1."},"assetId":{"type":"string","description":"Asset id from add_image (starts with as_)."},"flipX":{"type":"boolean"},"flipY":{"type":"boolean"},"crop":{"type":"object","properties":{"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1},"w":{"type":"number","minimum":0.01,"maximum":1},"h":{"type":"number","minimum":0.01,"maximum":1}},"required":["x","y","w","h"],"additionalProperties":false,"description":"Part of the image to show, as fractions 0..1 of its width and height."},"mask":{"type":"string","enum":["none","ellipse","rounded"],"description":"Clip shape for the image."},"radius":{"type":"number","minimum":0,"description":"Corner radius in pt."},"bleed":{"type":"boolean","description":"Lets the layer run off the page. Each edge must then go past the sheet edge or stay in the safe area. Not for text."}},"required":["type","id","x","y","width","height","rotation","opacity","assetId","flipX","flipY","mask","radius","bleed"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","enum":["text"]},"id":{"type":"string","description":"Layer id (starts with ly_)."},"name":{"type":"string","maxLength":80,"description":"Optional name to recognise the layer."},"x":{"type":"number","description":"Left edge in pt."},"y":{"type":"number","description":"Top edge in pt."},"width":{"type":"number","exclusiveMinimum":0,"description":"Width in pt."},"height":{"type":"number","exclusiveMinimum":0,"description":"Height in pt."},"rotation":{"type":"number","minimum":-180,"maximum":180,"description":"Degrees clockwise, around the layer centre."},"opacity":{"type":"number","minimum":0,"maximum":1,"description":"0..1."},"fit":{"type":"boolean","description":"true = the height follows the text (height was omitted)."},"text":{"type":"string","minLength":1,"maxLength":2000,"description":"The text. Line breaks with \\n. **bold** and [word]{#hex} for a coloured word."},"font":{"type":"string","enum":["andika","nunito","quicksand","literata","fraunces","fredoka","patrick-hand"],"description":"Font id. Default andika. See get_guide topic text."},"size":{"type":"number","minimum":6,"maximum":200,"description":"Font size in pt. Default 22. Story text 18-26."},"weight":{"type":"integer","minimum":100,"maximum":900,"description":"Font weight 100-900. Default 400."},"color":{"type":"string","description":"Colour as #rrggbb.","examples":["#FAF7F0"],"pattern":"^#[0-9a-fA-F]{6}$"},"align":{"type":"string","enum":["left","center","right"]},"valign":{"type":"string","enum":["top","middle","bottom"]},"lineHeight":{"type":"number","minimum":0.8,"maximum":3,"description":"Line height as a multiple of the size. Default depends on the font."},"letterSpacing":{"type":"number","minimum":-0.1,"maximum":0.5,"description":"In em. Default 0."}},"required":["type","id","x","y","width","height","rotation","opacity","fit","text","font","size","weight","color","align","valign","lineHeight","letterSpacing"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","enum":["shape"]},"id":{"type":"string","description":"Layer id (starts with ly_)."},"name":{"type":"string","maxLength":80,"description":"Optional name to recognise the layer."},"x":{"type":"number","description":"Left edge in pt."},"y":{"type":"number","description":"Top edge in pt."},"width":{"type":"number","exclusiveMinimum":0,"description":"Width in pt."},"height":{"type":"number","exclusiveMinimum":0,"description":"Height in pt."},"rotation":{"type":"number","minimum":-180,"maximum":180,"description":"Degrees clockwise, around the layer centre."},"opacity":{"type":"number","minimum":0,"maximum":1,"description":"0..1."},"shape":{"type":"string","enum":["rect","ellipse"]},"fill":{"type":"string","description":"Colour as #rrggbb.","examples":["#FAF7F0"],"pattern":"^#[0-9a-fA-F]{6}$"},"radius":{"type":"number","minimum":0,"description":"Corner radius in pt."},"bleed":{"type":"boolean","description":"Lets the layer run off the page. Each edge must then go past the sheet edge or stay in the safe area. Not for text."}},"required":["type","id","x","y","width","height","rotation","opacity","shape","fill","radius","bleed"],"additionalProperties":false}]},"description":"Bottom first. Left out when include has no \"layers\"."}},"required":["surface","background","backgroundOverride"],"additionalProperties":false},"pages":{"type":"array","items":{"type":"object","properties":{"surface":{"anyOf":[{"type":"string","enum":["cover"]},{"type":"integer","minimum":1,"maximum":84,"description":"1-based page number."}],"description":"\"cover\" or a 1-based page number. Page 1 is a right-hand page; spreads are 2+3, 4+5, ..."},"background":{"type":"string","description":"Colour as #rrggbb.","examples":["#FAF7F0"],"allOf":[{"pattern":"^#[0-9a-fA-F]{6}$","description":"Effective paper colour of this surface."}]},"backgroundOverride":{"type":"boolean","description":"true = this surface has its own colour instead of the book colour."},"note":{"type":"string"},"layers":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"id":{"type":"string","description":"Layer id (starts with ly_)."},"name":{"type":"string","maxLength":80,"description":"Optional name to recognise the layer."},"x":{"type":"number","description":"Left edge in pt."},"y":{"type":"number","description":"Top edge in pt."},"width":{"type":"number","exclusiveMinimum":0,"description":"Width in pt."},"height":{"type":"number","exclusiveMinimum":0,"description":"Height in pt."},"rotation":{"type":"number","minimum":-180,"maximum":180,"description":"Degrees clockwise, around the layer centre."},"opacity":{"type":"number","minimum":0,"maximum":1,"description":"0..1."},"assetId":{"type":"string","description":"Asset id from add_image (starts with as_)."},"flipX":{"type":"boolean"},"flipY":{"type":"boolean"},"crop":{"type":"object","properties":{"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1},"w":{"type":"number","minimum":0.01,"maximum":1},"h":{"type":"number","minimum":0.01,"maximum":1}},"required":["x","y","w","h"],"additionalProperties":false,"description":"Part of the image to show, as fractions 0..1 of its width and height."},"mask":{"type":"string","enum":["none","ellipse","rounded"],"description":"Clip shape for the image."},"radius":{"type":"number","minimum":0,"description":"Corner radius in pt."},"bleed":{"type":"boolean","description":"Lets the layer run off the page. Each edge must then go past the sheet edge or stay in the safe area. Not for text."}},"required":["type","id","x","y","width","height","rotation","opacity","assetId","flipX","flipY","mask","radius","bleed"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","enum":["text"]},"id":{"type":"string","description":"Layer id (starts with ly_)."},"name":{"type":"string","maxLength":80,"description":"Optional name to recognise the layer."},"x":{"type":"number","description":"Left edge in pt."},"y":{"type":"number","description":"Top edge in pt."},"width":{"type":"number","exclusiveMinimum":0,"description":"Width in pt."},"height":{"type":"number","exclusiveMinimum":0,"description":"Height in pt."},"rotation":{"type":"number","minimum":-180,"maximum":180,"description":"Degrees clockwise, around the layer centre."},"opacity":{"type":"number","minimum":0,"maximum":1,"description":"0..1."},"fit":{"type":"boolean","description":"true = the height follows the text (height was omitted)."},"text":{"type":"string","minLength":1,"maxLength":2000,"description":"The text. Line breaks with \\n. **bold** and [word]{#hex} for a coloured word."},"font":{"type":"string","enum":["andika","nunito","quicksand","literata","fraunces","fredoka","patrick-hand"],"description":"Font id. Default andika. See get_guide topic text."},"size":{"type":"number","minimum":6,"maximum":200,"description":"Font size in pt. Default 22. Story text 18-26."},"weight":{"type":"integer","minimum":100,"maximum":900,"description":"Font weight 100-900. Default 400."},"color":{"type":"string","description":"Colour as #rrggbb.","examples":["#FAF7F0"],"pattern":"^#[0-9a-fA-F]{6}$"},"align":{"type":"string","enum":["left","center","right"]},"valign":{"type":"string","enum":["top","middle","bottom"]},"lineHeight":{"type":"number","minimum":0.8,"maximum":3,"description":"Line height as a multiple of the size. Default depends on the font."},"letterSpacing":{"type":"number","minimum":-0.1,"maximum":0.5,"description":"In em. Default 0."}},"required":["type","id","x","y","width","height","rotation","opacity","fit","text","font","size","weight","color","align","valign","lineHeight","letterSpacing"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","enum":["shape"]},"id":{"type":"string","description":"Layer id (starts with ly_)."},"name":{"type":"string","maxLength":80,"description":"Optional name to recognise the layer."},"x":{"type":"number","description":"Left edge in pt."},"y":{"type":"number","description":"Top edge in pt."},"width":{"type":"number","exclusiveMinimum":0,"description":"Width in pt."},"height":{"type":"number","exclusiveMinimum":0,"description":"Height in pt."},"rotation":{"type":"number","minimum":-180,"maximum":180,"description":"Degrees clockwise, around the layer centre."},"opacity":{"type":"number","minimum":0,"maximum":1,"description":"0..1."},"shape":{"type":"string","enum":["rect","ellipse"]},"fill":{"type":"string","description":"Colour as #rrggbb.","examples":["#FAF7F0"],"pattern":"^#[0-9a-fA-F]{6}$"},"radius":{"type":"number","minimum":0,"description":"Corner radius in pt."},"bleed":{"type":"boolean","description":"Lets the layer run off the page. Each edge must then go past the sheet edge or stay in the safe area. Not for text."}},"required":["type","id","x","y","width","height","rotation","opacity","shape","fill","radius","bleed"],"additionalProperties":false}]},"description":"Bottom first. Left out when include has no \"layers\"."}},"required":["surface","background","backgroundOverride"],"additionalProperties":false}},"issues":{"type":"array","items":{"type":"object","properties":{"severity":{"type":"string","enum":["error","warning"],"description":"Errors block printing; warnings don't."},"code":{"type":"string","description":"e.g. outside_safe_area, text_overflow, low_resolution."},"surface":{"anyOf":[{"anyOf":[{"type":"string","enum":["cover"]},{"type":"integer","minimum":1,"maximum":84,"description":"1-based page number."}],"description":"\"cover\" or a 1-based page number. Page 1 is a right-hand page; spreads are 2+3, 4+5, ..."},{"type":"string","enum":["book"]}]},"layerId":{"type":"string","description":"Layer id (starts with ly_)."},"message":{"type":"string","description":"What is wrong, with numbers."},"fix":{"type":"string","description":"What to do."}},"required":["severity","code","surface","message","fix"],"additionalProperties":false},"description":"Print issues for the whole book."},"printReady":{"type":"boolean","description":"true = the whole book has no print errors."},"links":{"type":"object","properties":{"view":{"type":"string"}},"required":["view"],"additionalProperties":false}},"required":["version","title","background","pageCount","updatedAt","cover","pages","issues","printReady","links"],"additionalProperties":false}}}},"default":{"description":"ToolError: the call did nothing. See error.fix.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_input","book_not_found","version_conflict","page_not_found","layer_not_found","asset_not_found","upload_not_found","page_limits","image_missing","image_unusable","order_not_found","order_locked","auth_required","unavailable","rate_limited","internal"]},"message":{"type":"string"},"fix":{"type":"string","description":"What to change and retry."},"path":{"type":"string","description":"Field that caused it, e.g. \"ops[3].layer.x\"."},"retryable":{"type":"boolean"},"currentVersion":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["code","message","fix","retryable"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}},"x-mcp-tool":"view_book","x-annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":false,"idempotentHint":true}}},"/books/{bookId}/edits":{"post":{"operationId":"edit_book","summary":"Edit a book","description":"Apply a batch of ops to one book: pages, layers, text, colours, notes, restore (undo). All ops apply or none; one new version per call. Send baseVersion = the version you last saw. Returns print issues for the surfaces you touched. Lay out 2-4 spreads per call.","parameters":[{"name":"bookId","in":"path","required":true,"schema":{"type":"string","description":"The book id from create_book (starts with bk_). It is also the edit key: keep it private."}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"baseVersion":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"The version your edit is based on (from create_book, get_book or the last edit_book)."},"ops":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"op":{"type":"string","enum":["set_book"]},"title":{"type":"string","minLength":1,"maxLength":200},"notes":{"type":"string","maxLength":20000,"description":"The plan: manuscript, palette, style, characters."},"background":{"type":"string","description":"Colour as #rrggbb.","examples":["#FAF7F0"],"allOf":[{"pattern":"^#[0-9a-fA-F]{6}$","description":"Book paper colour. Every surface without an override follows it."}]}},"required":["op"],"additionalProperties":false,"description":"Change title, notes or the book colour."},{"type":"object","properties":{"op":{"type":"string","enum":["add_pages"]},"count":{"type":"integer","minimum":1,"maximum":84},"after":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Insert after this page. 0 = at the start. Default: at the end."}},"required":["op","count"],"additionalProperties":false,"description":"Add blank pages."},{"type":"object","properties":{"op":{"type":"string","enum":["delete_pages"]},"pages":{"type":"array","items":{"type":"integer","minimum":1,"maximum":84,"description":"1-based page number."},"minItems":1,"description":"Page numbers as they are before this op."}},"required":["op","pages"],"additionalProperties":false,"description":"Delete pages. Undo with restore."},{"type":"object","properties":{"op":{"type":"string","enum":["move_page"]},"from":{"type":"integer","minimum":1,"maximum":84,"description":"1-based page number."},"to":{"type":"integer","minimum":1,"maximum":84,"description":"Position the page ends up at."}},"required":["op","from","to"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","enum":["duplicate_page"]},"page":{"type":"integer","minimum":1,"maximum":84,"description":"The copy is inserted right after it."}},"required":["op","page"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","enum":["set_surface"]},"surface":{"anyOf":[{"type":"string","enum":["cover"]},{"type":"integer","minimum":1,"maximum":84,"description":"1-based page number."}],"description":"\"cover\" or a 1-based page number. Page 1 is a right-hand page; spreads are 2+3, 4+5, ..."},"background":{"anyOf":[{"type":"string","description":"Colour as #rrggbb.","examples":["#FAF7F0"],"pattern":"^#[0-9a-fA-F]{6}$"},{"type":"null"}],"description":"Own paper colour for this surface; null = follow the book colour again."},"note":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"description":"Your note for this page, e.g. its manuscript text."}},"required":["op","surface"],"additionalProperties":false,"description":"Page or cover colour override and note."},{"type":"object","properties":{"op":{"type":"string","enum":["add_layer"]},"surface":{"anyOf":[{"type":"string","enum":["cover"]},{"type":"integer","minimum":1,"maximum":84,"description":"1-based page number."}],"description":"\"cover\" or a 1-based page number. Page 1 is a right-hand page; spreads are 2+3, 4+5, ..."},"layer":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"name":{"type":"string","maxLength":80,"description":"Optional name to recognise the layer."},"x":{"type":"number","description":"Left edge in pt."},"y":{"type":"number","description":"Top edge in pt."},"rotation":{"type":"number","minimum":-180,"maximum":180,"description":"Degrees clockwise, around the layer centre."},"opacity":{"type":"number","minimum":0,"maximum":1,"description":"0..1."},"assetId":{"type":"string","description":"Asset id from add_image (starts with as_)."},"width":{"type":"number","exclusiveMinimum":0,"description":"Width in pt. The height follows the image's aspect ratio (after crop)."},"flipX":{"type":"boolean"},"flipY":{"type":"boolean"},"crop":{"type":"object","properties":{"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1},"w":{"type":"number","minimum":0.01,"maximum":1},"h":{"type":"number","minimum":0.01,"maximum":1}},"required":["x","y","w","h"],"additionalProperties":false,"description":"Part of the image to show, as fractions 0..1 of its width and height."},"mask":{"type":"string","enum":["none","ellipse","rounded"],"description":"Clip shape for the image."},"radius":{"type":"number","minimum":0,"description":"Corner radius in pt."},"bleed":{"type":"boolean","description":"Lets the layer run off the page. Each edge must then go past the sheet edge or stay in the safe area. Not for text."}},"required":["type","x","y","assetId","width"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","enum":["text"]},"name":{"type":"string","maxLength":80,"description":"Optional name to recognise the layer."},"x":{"type":"number","description":"Left edge in pt."},"y":{"type":"number","description":"Top edge in pt."},"rotation":{"type":"number","minimum":-180,"maximum":180,"description":"Degrees clockwise, around the layer centre."},"opacity":{"type":"number","minimum":0,"maximum":1,"description":"0..1."},"text":{"type":"string","minLength":1,"maxLength":2000,"description":"The text. Line breaks with \\n. **bold** and [word]{#hex} for a coloured word."},"width":{"type":"number","exclusiveMinimum":0,"description":"Frame width in pt. Lines wrap inside it."},"height":{"type":"number","exclusiveMinimum":0,"description":"Frame height in pt. Omit to make the frame fit the text."},"font":{"type":"string","enum":["andika","nunito","quicksand","literata","fraunces","fredoka","patrick-hand"],"description":"Font id. Default andika. See get_guide topic text."},"size":{"type":"number","minimum":6,"maximum":200,"description":"Font size in pt. Default 22. Story text 18-26."},"weight":{"type":"integer","minimum":100,"maximum":900,"description":"Font weight 100-900. Default 400."},"color":{"type":"string","description":"Colour as #rrggbb.","examples":["#FAF7F0"],"pattern":"^#[0-9a-fA-F]{6}$"},"align":{"type":"string","enum":["left","center","right"]},"valign":{"type":"string","enum":["top","middle","bottom"]},"lineHeight":{"type":"number","minimum":0.8,"maximum":3,"description":"Line height as a multiple of the size. Default depends on the font."},"letterSpacing":{"type":"number","minimum":-0.1,"maximum":0.5,"description":"In em. Default 0."}},"required":["type","x","y","text","width"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","enum":["shape"]},"name":{"type":"string","maxLength":80,"description":"Optional name to recognise the layer."},"x":{"type":"number","description":"Left edge in pt."},"y":{"type":"number","description":"Top edge in pt."},"rotation":{"type":"number","minimum":-180,"maximum":180,"description":"Degrees clockwise, around the layer centre."},"opacity":{"type":"number","minimum":0,"maximum":1,"description":"0..1."},"shape":{"type":"string","enum":["rect","ellipse"]},"fill":{"type":"string","description":"Colour as #rrggbb.","examples":["#FAF7F0"],"pattern":"^#[0-9a-fA-F]{6}$"},"width":{"type":"number","exclusiveMinimum":0,"description":"Width in pt."},"height":{"type":"number","exclusiveMinimum":0,"description":"Height in pt."},"radius":{"type":"number","minimum":0,"description":"Corner radius in pt."},"bleed":{"type":"boolean","description":"Lets the layer run off the page. Each edge must then go past the sheet edge or stay in the safe area. Not for text."}},"required":["type","x","y","shape","fill","width","height"],"additionalProperties":false}],"description":"A layer to add. \"type\" picks image, text or shape."},"ref":{"type":"string","minLength":1,"maxLength":40,"description":"A name for the new layer that later ops in the same call can use instead of its id."},"index":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Stack position, 0 = bottom. Default: top."}},"required":["op","surface","layer"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","enum":["update_layer"]},"layerId":{"type":"string","description":"Layer id, or a ref given earlier in this call."},"set":{"type":"object","properties":{"name":{"type":"string","maxLength":80,"description":"Optional name to recognise the layer."},"x":{"type":"number","description":"Left edge in pt."},"y":{"type":"number","description":"Top edge in pt."},"rotation":{"type":"number","minimum":-180,"maximum":180,"description":"Degrees clockwise, around the layer centre."},"opacity":{"type":"number","minimum":0,"maximum":1,"description":"0..1."},"bleed":{"type":"boolean","description":"Lets the layer run off the page. Each edge must then go past the sheet edge or stay in the safe area. Not for text."},"width":{"type":"number","exclusiveMinimum":0,"description":"Width in pt. Images keep their aspect ratio."},"height":{"anyOf":[{"type":"number","exclusiveMinimum":0,"description":"Height in pt. Text: null = fit the text. Images: not settable, it follows width."},{"type":"null"}]},"assetId":{"type":"string","description":"Asset id from add_image (starts with as_)."},"flipX":{"type":"boolean"},"flipY":{"type":"boolean"},"crop":{"anyOf":[{"type":"object","properties":{"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1},"w":{"type":"number","minimum":0.01,"maximum":1},"h":{"type":"number","minimum":0.01,"maximum":1}},"required":["x","y","w","h"],"additionalProperties":false,"description":"Part of the image to show, as fractions 0..1 of its width and height."},{"type":"null"}]},"mask":{"type":"string","enum":["none","ellipse","rounded"],"description":"Clip shape for the image."},"radius":{"type":"number","minimum":0,"description":"Corner radius in pt."},"text":{"type":"string","minLength":1,"maxLength":2000,"description":"The text. Line breaks with \\n. **bold** and [word]{#hex} for a coloured word."},"font":{"type":"string","enum":["andika","nunito","quicksand","literata","fraunces","fredoka","patrick-hand"],"description":"Font id. Default andika. See get_guide topic text."},"size":{"type":"number","minimum":6,"maximum":200,"description":"Font size in pt. Default 22. Story text 18-26."},"weight":{"type":"integer","minimum":100,"maximum":900,"description":"Font weight 100-900. Default 400."},"color":{"type":"string","description":"Colour as #rrggbb.","examples":["#FAF7F0"],"pattern":"^#[0-9a-fA-F]{6}$"},"align":{"type":"string","enum":["left","center","right"]},"valign":{"type":"string","enum":["top","middle","bottom"]},"lineHeight":{"type":"number","minimum":0.8,"maximum":3,"description":"Line height as a multiple of the size. Default depends on the font."},"letterSpacing":{"type":"number","minimum":-0.1,"maximum":0.5,"description":"In em. Default 0."},"shape":{"type":"string","enum":["rect","ellipse"]},"fill":{"type":"string","description":"Colour as #rrggbb.","examples":["#FAF7F0"],"pattern":"^#[0-9a-fA-F]{6}$"}},"additionalProperties":false,"description":"Fields to change. Only fields that apply to the layer's type are allowed."}},"required":["op","layerId","set"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","enum":["delete_layer"]},"layerId":{"type":"string","description":"Layer id, or a ref given earlier in this call."}},"required":["op","layerId"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","enum":["move_layer"]},"layerId":{"type":"string","description":"Layer id, or a ref given earlier in this call."},"to":{"anyOf":[{"type":"string","enum":["front","back"]},{"type":"integer","minimum":0,"maximum":9007199254740991}],"description":"\"front\", \"back\", or a stack index (0 = bottom)."},"surface":{"anyOf":[{"type":"string","enum":["cover"]},{"type":"integer","minimum":1,"maximum":84,"description":"1-based page number."}],"description":"Move the layer to this surface (same x, y)."}},"required":["op","layerId","to"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","enum":["copy_layer"]},"layerId":{"type":"string","description":"Layer id, or a ref given earlier in this call."},"surface":{"anyOf":[{"type":"string","enum":["cover"]},{"type":"integer","minimum":1,"maximum":84,"description":"1-based page number."}],"description":"\"cover\" or a 1-based page number. Page 1 is a right-hand page; spreads are 2+3, 4+5, ..."},"x":{"type":"number"},"y":{"type":"number"},"ref":{"type":"string","minLength":1,"maxLength":40,"description":"A name for the new layer that later ops in the same call can use instead of its id."}},"required":["op","layerId","surface"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","enum":["restore"]},"version":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"Make the book look like this version again. Creates a new version; nothing is lost."}},"required":["op","version"],"additionalProperties":false}]},"minItems":1,"maxItems":100,"description":"1..100 ops, applied in order."}},"required":["baseVersion","ops"],"additionalProperties":false}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"version":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"The new version. Use it as baseVersion next time."},"applied":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"created":{"type":"object","additionalProperties":{"type":"string"},"description":"ref → layer id for layers added with a ref."},"touched":{"type":"array","items":{"anyOf":[{"type":"string","enum":["cover"]},{"type":"integer","minimum":1,"maximum":84,"description":"1-based page number."}],"description":"\"cover\" or a 1-based page number. Page 1 is a right-hand page; spreads are 2+3, 4+5, ..."}},"issues":{"type":"array","items":{"type":"object","properties":{"severity":{"type":"string","enum":["error","warning"],"description":"Errors block printing; warnings don't."},"code":{"type":"string","description":"e.g. outside_safe_area, text_overflow, low_resolution."},"surface":{"anyOf":[{"anyOf":[{"type":"string","enum":["cover"]},{"type":"integer","minimum":1,"maximum":84,"description":"1-based page number."}],"description":"\"cover\" or a 1-based page number. Page 1 is a right-hand page; spreads are 2+3, 4+5, ..."},{"type":"string","enum":["book"]}]},"layerId":{"type":"string","description":"Layer id (starts with ly_)."},"message":{"type":"string","description":"What is wrong, with numbers."},"fix":{"type":"string","description":"What to do."}},"required":["severity","code","surface","message","fix"],"additionalProperties":false},"description":"Print issues on the touched surfaces (and book-level ones if pages changed)."},"adjustments":{"type":"array","items":{"type":"string"},"description":"Anything the server changed or decided for you."},"printReady":{"type":"boolean","description":"true = no blocking print errors in the whole book (see readiness)."},"readiness":{"type":"object","properties":{"printReady":{"type":"boolean","description":"No blocking print errors. Says nothing about whether the book is finished."},"complete":{"type":"boolean","description":"No blank pages and a title on the cover."},"blankPages":{"type":"array","items":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"warnings":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Non-blocking issues, e.g. pictures below 240 ppi (print soft)."},"summary":{"type":"string","description":"One sentence for people: what's left to do."}},"required":["printReady","complete","blankPages","warnings","summary"],"additionalProperties":false,"description":"How far the book is. Done = printReady and complete, ideally with 0 warnings."}},"required":["version","applied","created","touched","issues","adjustments","printReady","readiness"],"additionalProperties":false}}}},"default":{"description":"ToolError: the call did nothing. See error.fix.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_input","book_not_found","version_conflict","page_not_found","layer_not_found","asset_not_found","upload_not_found","page_limits","image_missing","image_unusable","order_not_found","order_locked","auth_required","unavailable","rate_limited","internal"]},"message":{"type":"string"},"fix":{"type":"string","description":"What to change and retry."},"path":{"type":"string","description":"Field that caused it, e.g. \"ops[3].layer.x\"."},"retryable":{"type":"boolean"},"currentVersion":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["code","message","fix","retryable"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}},"x-mcp-tool":"edit_book","x-annotations":{"readOnlyHint":false,"destructiveHint":false,"openWorldHint":false,"idempotentHint":false}}},"/books/{bookId}/assets":{"post":{"operationId":"add_image","summary":"Add an image","description":"Turn a picture into a book asset (does not place it; place it with edit_book add_layer). Give exactly one source: url, uploadId (from create_upload_url), base64, or image (ChatGPT file). Prefer transparent PNG cut-outs. Returns size, transparency, max sharp print width and a preview.","parameters":[{"name":"bookId","in":"path","required":true,"schema":{"type":"string","description":"The book id from create_book (starts with bk_). It is also the edit key: keep it private."}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"label":{"type":"string","minLength":1,"maxLength":200,"description":"What it shows, e.g. \"Mila jumping, side view\"."},"image":{"anyOf":[{"type":"object","properties":{"download_url":{"type":"string"},"file_id":{"type":"string"},"mime_type":{"type":"string"},"file_name":{"type":"string"}},"required":["download_url","file_id"],"additionalProperties":false},{"type":"string"}],"description":"ChatGPT file reference ({download_url, file_id}). A bare string is treated as a URL."},"url":{"type":"string","description":"Public http(s) URL of the image."},"uploadId":{"type":"string","description":"From create_upload_url, after you PUT the file."},"base64":{"type":"string","description":"The file as base64 (a data: URL prefix is fine). Small files only."},"trim":{"type":"boolean","description":"Crop transparent margins. Default true."}},"required":["label"],"additionalProperties":false}},"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"},"label":{"type":"string"},"trim":{"type":"boolean"}},"required":["file","label"]}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"assetId":{"type":"string","description":"Asset id from add_image (starts with as_)."},"label":{"type":"string"},"width":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Pixels."},"height":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Pixels."},"hasAlpha":{"type":"boolean","description":"true = has transparent parts (a cut-out)."},"maxWidthPt":{"type":"number","description":"Widest placement in pt that still prints sharp (240 ppi). Above 150 ppi is an error."},"idealWidthPt":{"type":"number","description":"Width in pt at 300 ppi."},"url":{"type":"string","description":"Public URL of the stored image."},"note":{"type":"string","description":"Something to know about the image (trimmed, opaque background, ...)."},"fix":{"type":"string","description":"What to do about the note, if anything."}},"required":["assetId","label","width","height","hasAlpha","maxWidthPt","idealWidthPt","url"],"additionalProperties":false}}}},"default":{"description":"ToolError: the call did nothing. See error.fix.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_input","book_not_found","version_conflict","page_not_found","layer_not_found","asset_not_found","upload_not_found","page_limits","image_missing","image_unusable","order_not_found","order_locked","auth_required","unavailable","rate_limited","internal"]},"message":{"type":"string"},"fix":{"type":"string","description":"What to change and retry."},"path":{"type":"string","description":"Field that caused it, e.g. \"ops[3].layer.x\"."},"retryable":{"type":"boolean"},"currentVersion":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["code","message","fix","retryable"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}},"x-mcp-tool":"add_image","x-annotations":{"readOnlyHint":false,"destructiveHint":false,"openWorldHint":true,"idempotentHint":false}}},"/books/{bookId}/uploads":{"post":{"operationId":"create_upload_url","summary":"Create upload links","description":"For agents with a shell or HTTP client (Codex, Claude Code): get one-time URLs to PUT local image files to. PUT with ?label=... and each file becomes a book asset right away (no add_image call needed). Ask for all the links you need at once with count.","parameters":[{"name":"bookId","in":"path","required":true,"schema":{"type":"string","description":"The book id from create_book (starts with bk_). It is also the edit key: keep it private."}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"count":{"type":"integer","minimum":1,"maximum":50,"description":"How many links. Default 1, max 50."}},"required":[],"additionalProperties":false}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"uploads":{"type":"array","items":{"type":"object","properties":{"uploadId":{"type":"string"},"uploadUrl":{"type":"string","description":"PUT the raw file here. Add ?label=... to turn it into a book asset in the same step (the response is the add_image result)."}},"required":["uploadId","uploadUrl"],"additionalProperties":false}},"method":{"type":"string","enum":["PUT"]},"expiresAt":{"type":"string","description":"ISO time; the links work for one hour, once each."},"howTo":{"type":"string"}},"required":["uploads","method","expiresAt","howTo"],"additionalProperties":false}}}},"default":{"description":"ToolError: the call did nothing. See error.fix.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_input","book_not_found","version_conflict","page_not_found","layer_not_found","asset_not_found","upload_not_found","page_limits","image_missing","image_unusable","order_not_found","order_locked","auth_required","unavailable","rate_limited","internal"]},"message":{"type":"string"},"fix":{"type":"string","description":"What to change and retry."},"path":{"type":"string","description":"Field that caused it, e.g. \"ops[3].layer.x\"."},"retryable":{"type":"boolean"},"currentVersion":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["code","message","fix","retryable"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}},"x-mcp-tool":"create_upload_url","x-annotations":{"readOnlyHint":false,"destructiveHint":false,"openWorldHint":false,"idempotentHint":false}}},"/books/{bookId}/renders":{"post":{"operationId":"render","summary":"See pages","description":"A picture (JPEG) of pages, a spread or the whole book as a contact sheet, exactly as it will print. Use it to judge your layout like an art director. guides: true draws the trim (red) and safe area (green).","parameters":[{"name":"bookId","in":"path","required":true,"schema":{"type":"string","description":"The book id from create_book (starts with bk_). It is also the edit key: keep it private."}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"what":{"anyOf":[{"type":"object","properties":{"pages":{"type":"array","items":{"anyOf":[{"type":"string","enum":["cover"]},{"type":"integer","minimum":1,"maximum":84,"description":"1-based page number."}],"description":"\"cover\" or a 1-based page number. Page 1 is a right-hand page; spreads are 2+3, 4+5, ..."},"minItems":1,"maxItems":6,"description":"Up to 6 surfaces, e.g. [\"cover\", 3]."}},"required":["pages"],"additionalProperties":false},{"type":"object","properties":{"spread":{"type":"integer","minimum":1,"maximum":84,"description":"Any page of the spread. 1 = page 1 alone; 2 or 3 = spread 2+3."}},"required":["spread"],"additionalProperties":false},{"type":"object","properties":{"contactSheet":{"type":"boolean","enum":[true],"description":"Cover plus every spread, small. Best check before ordering."}},"required":["contactSheet"],"additionalProperties":false}],"description":"What to draw: { pages }, { spread } or { contactSheet: true }."},"guides":{"type":"boolean","description":"Draw trim and safe-area lines. Default false."},"widthPx":{"type":"integer","minimum":400,"maximum":2400,"description":"Image width. Default 1200 (contact sheet 1600)."}},"required":["what"],"additionalProperties":false}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"version":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"The book version this picture shows."},"imageUrl":{"type":"string","description":"The picture (JPEG). MCP results also carry it as image content."},"issues":{"type":"array","items":{"type":"object","properties":{"severity":{"type":"string","enum":["error","warning"],"description":"Errors block printing; warnings don't."},"code":{"type":"string","description":"e.g. outside_safe_area, text_overflow, low_resolution."},"surface":{"anyOf":[{"anyOf":[{"type":"string","enum":["cover"]},{"type":"integer","minimum":1,"maximum":84,"description":"1-based page number."}],"description":"\"cover\" or a 1-based page number. Page 1 is a right-hand page; spreads are 2+3, 4+5, ..."},{"type":"string","enum":["book"]}]},"layerId":{"type":"string","description":"Layer id (starts with ly_)."},"message":{"type":"string","description":"What is wrong, with numbers."},"fix":{"type":"string","description":"What to do."}},"required":["severity","code","surface","message","fix"],"additionalProperties":false},"description":"Print issues on the drawn surfaces (and book-level ones)."},"printReady":{"type":"boolean"}},"required":["version","imageUrl","issues","printReady"],"additionalProperties":false}}}},"default":{"description":"ToolError: the call did nothing. See error.fix.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_input","book_not_found","version_conflict","page_not_found","layer_not_found","asset_not_found","upload_not_found","page_limits","image_missing","image_unusable","order_not_found","order_locked","auth_required","unavailable","rate_limited","internal"]},"message":{"type":"string"},"fix":{"type":"string","description":"What to change and retry."},"path":{"type":"string","description":"Field that caused it, e.g. \"ops[3].layer.x\"."},"retryable":{"type":"boolean"},"currentVersion":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["code","message","fix","retryable"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}},"x-mcp-tool":"render","x-annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":false,"idempotentHint":true}}},"/orders":{"post":{"operationId":"create_order","summary":"Order the printed book","description":"Start an order for the book as it is at baseVersion (frozen: later edits don't change it). Runs the print check first. Give email, shippingAddress and shippingLevel now or later with update_order. When nothing is missing, the order has a checkoutUrl: give it to the user to pay (only a person pays). €39 per copy + shipping.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"bookId":{"type":"string","description":"The book id from create_book (starts with bk_). It is also the edit key: keep it private."},"baseVersion":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"The version to print: the one you last saw."},"quantity":{"type":"integer","minimum":1,"maximum":10,"description":"Copies, 1-10. Default 1."},"email":{"type":"string","maxLength":254,"description":"The buyer's email: receipt, updates, and the link to keep the book."},"shippingAddress":{"type":"object","properties":{"name":{"type":"string","description":"Recipient's first and last name. May differ from the buyer (gifts)."},"line1":{"type":"string","description":"Street and number. Max 30 characters."},"line2":{"type":"string","description":"Apartment, floor, etc. Max 30 characters."},"city":{"type":"string"},"state":{"type":"string","description":"State or province code. Required for US, CA, AU, MX, JP, BR, IN."},"postcode":{"type":"string"},"country":{"type":"string","description":"ISO-2 country code. We ship to: NL, BE, DE, FR, LU, AT, IE, ES, PT, IT, DK, SE, FI, NO, CH, GB, PL, CZ, GR, HU, RO, BG, HR, SI, SK, EE, LV, LT, IS, MT, CY, US, CA, AU, NZ, JP, SG."},"phone":{"type":"string","description":"Phone number for the courier, e.g. +31 6 1234 5678."}},"required":["name","line1","city","postcode","country","phone"],"additionalProperties":false,"description":"Shipping address."},"shippingLevel":{"type":"string","description":"One of the order's shippingOptions[].level."},"acceptSuggestion":{"type":"boolean","description":"true = use the printer's addressSuggestion instead of the typed address."},"keepAddress":{"type":"boolean","description":"true = the user keeps their address as typed, ignoring addressSuggestion."}},"required":["bookId","baseVersion"],"additionalProperties":false}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ready":{"type":"boolean","description":"false = the book has print errors; nothing was ordered."},"order":{"type":"object","properties":{"orderId":{"type":"string","description":"Order id from create_order (starts with or_). Also the key to change the unpaid order: keep it private."},"bookId":{"type":"string"},"bookVersion":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The frozen book version this order prints. Later edits don't change it."},"title":{"type":"string"},"status":{"type":"string","enum":["draft","awaiting_payment","paid","sent_to_printer","printing","shipped","needs_attention","refunded"]},"quantity":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"email":{"type":"string"},"shippingAddress":{"type":"object","properties":{"name":{"type":"string","description":"Recipient's first and last name. May differ from the buyer (gifts)."},"line1":{"type":"string","description":"Street and number. Max 30 characters."},"line2":{"type":"string","description":"Apartment, floor, etc. Max 30 characters."},"city":{"type":"string"},"state":{"type":"string","description":"State or province code. Required for US, CA, AU, MX, JP, BR, IN."},"postcode":{"type":"string"},"country":{"type":"string","description":"ISO-2 country code. We ship to: NL, BE, DE, FR, LU, AT, IE, ES, PT, IT, DK, SE, FI, NO, CH, GB, PL, CZ, GR, HU, RO, BG, HR, SI, SK, EE, LV, LT, IS, MT, CY, US, CA, AU, NZ, JP, SG."},"phone":{"type":"string","description":"Phone number for the courier, e.g. +31 6 1234 5678."}},"required":["name","line1","city","postcode","country","phone"],"additionalProperties":false,"description":"Shipping address."},"addressSuggestion":{"type":"object","properties":{"name":{"type":"string","description":"Recipient's first and last name. May differ from the buyer (gifts)."},"line1":{"type":"string","description":"Street and number. Max 30 characters."},"line2":{"type":"string","description":"Apartment, floor, etc. Max 30 characters."},"city":{"type":"string"},"state":{"type":"string","description":"State or province code. Required for US, CA, AU, MX, JP, BR, IN."},"postcode":{"type":"string"},"country":{"type":"string","description":"ISO-2 country code. We ship to: NL, BE, DE, FR, LU, AT, IE, ES, PT, IT, DK, SE, FI, NO, CH, GB, PL, CZ, GR, HU, RO, BG, HR, SI, SK, EE, LV, LT, IS, MT, CY, US, CA, AU, NZ, JP, SG."},"phone":{"type":"string","description":"Phone number for the courier, e.g. +31 6 1234 5678."}},"required":["name","line1","city","postcode","country","phone"],"additionalProperties":false,"description":"The printer's corrected version of the address. Ask the user: use it (acceptSuggestion) or keep theirs (keepAddress)."},"shippingOptions":{"type":"array","items":{"type":"object","properties":{"level":{"type":"string","description":"Pass this as shippingLevel."},"label":{"type":"string"},"carrier":{"anyOf":[{"type":"string"},{"type":"null"}]},"estimatedDelivery":{"type":"string","description":"e.g. \"Arrives Nov 3 – Nov 7\"."},"shippingCents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"totalCents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Total for the whole order with this option."}},"required":["level","label","carrier","estimatedDelivery","shippingCents","totalCents"],"additionalProperties":false}},"shippingLevel":{"type":"string"},"price":{"type":"object","properties":{"booksCents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Book price × quantity, VAT included."},"shippingCents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Shipping, tax included."},"totalCents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"currency":{"type":"string"},"display":{"type":"string","description":"Total for people, e.g. \"€47.24\"."}},"required":["booksCents","shippingCents","totalCents","currency","display"],"additionalProperties":false},"missing":{"type":"array","items":{"type":"string","enum":["email","shippingAddress","addressCheck","shippingLevel"]},"description":"What is left before payment. \"addressCheck\" = the printer suggests a corrected address; the user must choose."},"checkoutUrl":{"type":"string","description":"The payment page on papergarden.ai. Give it to the user; only a person pays."},"tracking":{"type":"object","properties":{"url":{"type":"string"}},"required":["url"],"additionalProperties":false},"problem":{"type":"object","properties":{"message":{"type":"string"},"fix":{"type":"string"}},"required":["message","fix"],"additionalProperties":false},"next":{"type":"string","description":"What to do now."}},"required":["orderId","bookId","bookVersion","title","status","quantity","missing","next"],"additionalProperties":false},"issues":{"type":"array","items":{"type":"object","properties":{"severity":{"type":"string","enum":["error","warning"],"description":"Errors block printing; warnings don't."},"code":{"type":"string","description":"e.g. outside_safe_area, text_overflow, low_resolution."},"surface":{"anyOf":[{"anyOf":[{"type":"string","enum":["cover"]},{"type":"integer","minimum":1,"maximum":84,"description":"1-based page number."}],"description":"\"cover\" or a 1-based page number. Page 1 is a right-hand page; spreads are 2+3, 4+5, ..."},{"type":"string","enum":["book"]}]},"layerId":{"type":"string","description":"Layer id (starts with ly_)."},"message":{"type":"string","description":"What is wrong, with numbers."},"fix":{"type":"string","description":"What to do."}},"required":["severity","code","surface","message","fix"],"additionalProperties":false},"description":"Print errors to fix first (when ready is false)."}},"required":["ready","issues"],"additionalProperties":false}}}},"default":{"description":"ToolError: the call did nothing. See error.fix.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_input","book_not_found","version_conflict","page_not_found","layer_not_found","asset_not_found","upload_not_found","page_limits","image_missing","image_unusable","order_not_found","order_locked","auth_required","unavailable","rate_limited","internal"]},"message":{"type":"string"},"fix":{"type":"string","description":"What to change and retry."},"path":{"type":"string","description":"Field that caused it, e.g. \"ops[3].layer.x\"."},"retryable":{"type":"boolean"},"currentVersion":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["code","message","fix","retryable"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}},"x-mcp-tool":"create_order","x-annotations":{"readOnlyHint":false,"destructiveHint":false,"openWorldHint":true,"idempotentHint":false}},"get":{"operationId":"get_orders","summary":"Check orders","description":"One order (orderId) or all orders of a book (bookId): status, price, payment link, tracking, problems. Read-only.","parameters":[{"name":"orderId","in":"query","required":false,"description":"Order id from create_order (starts with or_). Also the key to change the unpaid order: keep it private.","schema":{"type":"string","description":"Order id from create_order (starts with or_). Also the key to change the unpaid order: keep it private."}},{"name":"bookId","in":"query","required":false,"description":"The book id from create_book (starts with bk_). It is also the edit key: keep it private.","schema":{"type":"string","description":"The book id from create_book (starts with bk_). It is also the edit key: keep it private."}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"orders":{"type":"array","items":{"type":"object","properties":{"orderId":{"type":"string","description":"Order id from create_order (starts with or_). Also the key to change the unpaid order: keep it private."},"bookId":{"type":"string"},"bookVersion":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The frozen book version this order prints. Later edits don't change it."},"title":{"type":"string"},"status":{"type":"string","enum":["draft","awaiting_payment","paid","sent_to_printer","printing","shipped","needs_attention","refunded"]},"quantity":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"email":{"type":"string"},"shippingAddress":{"type":"object","properties":{"name":{"type":"string","description":"Recipient's first and last name. May differ from the buyer (gifts)."},"line1":{"type":"string","description":"Street and number. Max 30 characters."},"line2":{"type":"string","description":"Apartment, floor, etc. Max 30 characters."},"city":{"type":"string"},"state":{"type":"string","description":"State or province code. Required for US, CA, AU, MX, JP, BR, IN."},"postcode":{"type":"string"},"country":{"type":"string","description":"ISO-2 country code. We ship to: NL, BE, DE, FR, LU, AT, IE, ES, PT, IT, DK, SE, FI, NO, CH, GB, PL, CZ, GR, HU, RO, BG, HR, SI, SK, EE, LV, LT, IS, MT, CY, US, CA, AU, NZ, JP, SG."},"phone":{"type":"string","description":"Phone number for the courier, e.g. +31 6 1234 5678."}},"required":["name","line1","city","postcode","country","phone"],"additionalProperties":false,"description":"Shipping address."},"addressSuggestion":{"type":"object","properties":{"name":{"type":"string","description":"Recipient's first and last name. May differ from the buyer (gifts)."},"line1":{"type":"string","description":"Street and number. Max 30 characters."},"line2":{"type":"string","description":"Apartment, floor, etc. Max 30 characters."},"city":{"type":"string"},"state":{"type":"string","description":"State or province code. Required for US, CA, AU, MX, JP, BR, IN."},"postcode":{"type":"string"},"country":{"type":"string","description":"ISO-2 country code. We ship to: NL, BE, DE, FR, LU, AT, IE, ES, PT, IT, DK, SE, FI, NO, CH, GB, PL, CZ, GR, HU, RO, BG, HR, SI, SK, EE, LV, LT, IS, MT, CY, US, CA, AU, NZ, JP, SG."},"phone":{"type":"string","description":"Phone number for the courier, e.g. +31 6 1234 5678."}},"required":["name","line1","city","postcode","country","phone"],"additionalProperties":false,"description":"The printer's corrected version of the address. Ask the user: use it (acceptSuggestion) or keep theirs (keepAddress)."},"shippingOptions":{"type":"array","items":{"type":"object","properties":{"level":{"type":"string","description":"Pass this as shippingLevel."},"label":{"type":"string"},"carrier":{"anyOf":[{"type":"string"},{"type":"null"}]},"estimatedDelivery":{"type":"string","description":"e.g. \"Arrives Nov 3 – Nov 7\"."},"shippingCents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"totalCents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Total for the whole order with this option."}},"required":["level","label","carrier","estimatedDelivery","shippingCents","totalCents"],"additionalProperties":false}},"shippingLevel":{"type":"string"},"price":{"type":"object","properties":{"booksCents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Book price × quantity, VAT included."},"shippingCents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Shipping, tax included."},"totalCents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"currency":{"type":"string"},"display":{"type":"string","description":"Total for people, e.g. \"€47.24\"."}},"required":["booksCents","shippingCents","totalCents","currency","display"],"additionalProperties":false},"missing":{"type":"array","items":{"type":"string","enum":["email","shippingAddress","addressCheck","shippingLevel"]},"description":"What is left before payment. \"addressCheck\" = the printer suggests a corrected address; the user must choose."},"checkoutUrl":{"type":"string","description":"The payment page on papergarden.ai. Give it to the user; only a person pays."},"tracking":{"type":"object","properties":{"url":{"type":"string"}},"required":["url"],"additionalProperties":false},"problem":{"type":"object","properties":{"message":{"type":"string"},"fix":{"type":"string"}},"required":["message","fix"],"additionalProperties":false},"next":{"type":"string","description":"What to do now."}},"required":["orderId","bookId","bookVersion","title","status","quantity","missing","next"],"additionalProperties":false}}},"required":["orders"],"additionalProperties":false}}}},"default":{"description":"ToolError: the call did nothing. See error.fix.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_input","book_not_found","version_conflict","page_not_found","layer_not_found","asset_not_found","upload_not_found","page_limits","image_missing","image_unusable","order_not_found","order_locked","auth_required","unavailable","rate_limited","internal"]},"message":{"type":"string"},"fix":{"type":"string","description":"What to change and retry."},"path":{"type":"string","description":"Field that caused it, e.g. \"ops[3].layer.x\"."},"retryable":{"type":"boolean"},"currentVersion":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["code","message","fix","retryable"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}},"x-mcp-tool":"get_orders","x-annotations":{"readOnlyHint":true,"destructiveHint":false,"openWorldHint":false,"idempotentHint":true}}},"/orders/{orderId}":{"patch":{"operationId":"update_order","summary":"Change an unpaid order","description":"Set or change quantity, email, shippingAddress (returns live shippingOptions with prices) or shippingLevel on an unpaid order. When nothing is missing, the order gets a checkoutUrl for the user to pay. Same input twice gives the same order.","parameters":[{"name":"orderId","in":"path","required":true,"schema":{"type":"string","description":"Order id from create_order (starts with or_). Also the key to change the unpaid order: keep it private."}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"quantity":{"type":"integer","minimum":1,"maximum":10,"description":"Copies, 1-10. Default 1."},"email":{"type":"string","maxLength":254,"description":"The buyer's email: receipt, updates, and the link to keep the book."},"shippingAddress":{"type":"object","properties":{"name":{"type":"string","description":"Recipient's first and last name. May differ from the buyer (gifts)."},"line1":{"type":"string","description":"Street and number. Max 30 characters."},"line2":{"type":"string","description":"Apartment, floor, etc. Max 30 characters."},"city":{"type":"string"},"state":{"type":"string","description":"State or province code. Required for US, CA, AU, MX, JP, BR, IN."},"postcode":{"type":"string"},"country":{"type":"string","description":"ISO-2 country code. We ship to: NL, BE, DE, FR, LU, AT, IE, ES, PT, IT, DK, SE, FI, NO, CH, GB, PL, CZ, GR, HU, RO, BG, HR, SI, SK, EE, LV, LT, IS, MT, CY, US, CA, AU, NZ, JP, SG."},"phone":{"type":"string","description":"Phone number for the courier, e.g. +31 6 1234 5678."}},"required":["name","line1","city","postcode","country","phone"],"additionalProperties":false,"description":"Shipping address."},"shippingLevel":{"type":"string","description":"One of the order's shippingOptions[].level."},"acceptSuggestion":{"type":"boolean","description":"true = use the printer's addressSuggestion instead of the typed address."},"keepAddress":{"type":"boolean","description":"true = the user keeps their address as typed, ignoring addressSuggestion."}},"required":[],"additionalProperties":false}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"order":{"type":"object","properties":{"orderId":{"type":"string","description":"Order id from create_order (starts with or_). Also the key to change the unpaid order: keep it private."},"bookId":{"type":"string"},"bookVersion":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The frozen book version this order prints. Later edits don't change it."},"title":{"type":"string"},"status":{"type":"string","enum":["draft","awaiting_payment","paid","sent_to_printer","printing","shipped","needs_attention","refunded"]},"quantity":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"email":{"type":"string"},"shippingAddress":{"type":"object","properties":{"name":{"type":"string","description":"Recipient's first and last name. May differ from the buyer (gifts)."},"line1":{"type":"string","description":"Street and number. Max 30 characters."},"line2":{"type":"string","description":"Apartment, floor, etc. Max 30 characters."},"city":{"type":"string"},"state":{"type":"string","description":"State or province code. Required for US, CA, AU, MX, JP, BR, IN."},"postcode":{"type":"string"},"country":{"type":"string","description":"ISO-2 country code. We ship to: NL, BE, DE, FR, LU, AT, IE, ES, PT, IT, DK, SE, FI, NO, CH, GB, PL, CZ, GR, HU, RO, BG, HR, SI, SK, EE, LV, LT, IS, MT, CY, US, CA, AU, NZ, JP, SG."},"phone":{"type":"string","description":"Phone number for the courier, e.g. +31 6 1234 5678."}},"required":["name","line1","city","postcode","country","phone"],"additionalProperties":false,"description":"Shipping address."},"addressSuggestion":{"type":"object","properties":{"name":{"type":"string","description":"Recipient's first and last name. May differ from the buyer (gifts)."},"line1":{"type":"string","description":"Street and number. Max 30 characters."},"line2":{"type":"string","description":"Apartment, floor, etc. Max 30 characters."},"city":{"type":"string"},"state":{"type":"string","description":"State or province code. Required for US, CA, AU, MX, JP, BR, IN."},"postcode":{"type":"string"},"country":{"type":"string","description":"ISO-2 country code. We ship to: NL, BE, DE, FR, LU, AT, IE, ES, PT, IT, DK, SE, FI, NO, CH, GB, PL, CZ, GR, HU, RO, BG, HR, SI, SK, EE, LV, LT, IS, MT, CY, US, CA, AU, NZ, JP, SG."},"phone":{"type":"string","description":"Phone number for the courier, e.g. +31 6 1234 5678."}},"required":["name","line1","city","postcode","country","phone"],"additionalProperties":false,"description":"The printer's corrected version of the address. Ask the user: use it (acceptSuggestion) or keep theirs (keepAddress)."},"shippingOptions":{"type":"array","items":{"type":"object","properties":{"level":{"type":"string","description":"Pass this as shippingLevel."},"label":{"type":"string"},"carrier":{"anyOf":[{"type":"string"},{"type":"null"}]},"estimatedDelivery":{"type":"string","description":"e.g. \"Arrives Nov 3 – Nov 7\"."},"shippingCents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"totalCents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Total for the whole order with this option."}},"required":["level","label","carrier","estimatedDelivery","shippingCents","totalCents"],"additionalProperties":false}},"shippingLevel":{"type":"string"},"price":{"type":"object","properties":{"booksCents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Book price × quantity, VAT included."},"shippingCents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Shipping, tax included."},"totalCents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"currency":{"type":"string"},"display":{"type":"string","description":"Total for people, e.g. \"€47.24\"."}},"required":["booksCents","shippingCents","totalCents","currency","display"],"additionalProperties":false},"missing":{"type":"array","items":{"type":"string","enum":["email","shippingAddress","addressCheck","shippingLevel"]},"description":"What is left before payment. \"addressCheck\" = the printer suggests a corrected address; the user must choose."},"checkoutUrl":{"type":"string","description":"The payment page on papergarden.ai. Give it to the user; only a person pays."},"tracking":{"type":"object","properties":{"url":{"type":"string"}},"required":["url"],"additionalProperties":false},"problem":{"type":"object","properties":{"message":{"type":"string"},"fix":{"type":"string"}},"required":["message","fix"],"additionalProperties":false},"next":{"type":"string","description":"What to do now."}},"required":["orderId","bookId","bookVersion","title","status","quantity","missing","next"],"additionalProperties":false}},"required":["order"],"additionalProperties":false}}}},"default":{"description":"ToolError: the call did nothing. See error.fix.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_input","book_not_found","version_conflict","page_not_found","layer_not_found","asset_not_found","upload_not_found","page_limits","image_missing","image_unusable","order_not_found","order_locked","auth_required","unavailable","rate_limited","internal"]},"message":{"type":"string"},"fix":{"type":"string","description":"What to change and retry."},"path":{"type":"string","description":"Field that caused it, e.g. \"ops[3].layer.x\"."},"retryable":{"type":"boolean"},"currentVersion":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["code","message","fix","retryable"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}},"x-mcp-tool":"update_order","x-annotations":{"readOnlyHint":false,"destructiveHint":false,"openWorldHint":true,"idempotentHint":true}}}}}