{"openapi":"3.1.0","info":{"title":"I'm In The Book Public API","description":"The **I'm In The Book Public API** exposes read-only catalog data about I'm In The Book, the\npersonalized keepsake storybook store: current prices, illustration styles, the story\nscenes a customer can choose from, and the gift-occasion landing pages we publish.\n\nIt is designed to be easy for software (including autonomous agents) to consume: every\nendpoint is a `GET`, every response is JSON, and this schema is published at\n`https://iminthebook.com/openapi.json`.\n\n## Base URL and versioning\n\nAll endpoints live under `https://iminthebook.com/api/v1/`. The API is versioned in the URL\npath. The current version is `v1` (contract version 1.0.0).\n\n## Deprecation policy\n\nBackwards-incompatible changes are never made in place. A breaking change ships as a new\nversion path (for example `/api/v2/`), and the previous version keeps working. When an\nendpoint or version is scheduled for removal it is announced **at least 6 months in\nadvance**: deprecated responses carry the `Deprecation` and `Sunset` response headers, and\nthe retirement date is published on https://iminthebook.com/developers. Additive changes (new endpoints,\nnew optional fields) can happen at any time within a version, so clients should ignore\nunknown JSON fields rather than failing on them.\n\n## Rate limits\n\nRequests are limited to **60 requests per minute per IP address**. Every response to a\n`/api/v1` request carries RFC-style rate limit headers:\n\n```\nRateLimit-Policy: \"default\";q=60;w=60\nRateLimit: \"default\";r=59;t=42\n```\n\n`q` is the quota, `w` the window in seconds, `r` the requests remaining in the current\nwindow and `t` the seconds until the window resets. Exceeding the limit returns\n`429 Too Many Requests` with a `Retry-After` header giving the number of seconds to wait.\n\n## Authentication\n\nNone. Every endpoint is public and read-only. There are no API keys to request and no\npersonal or order data is exposed. Placing an order remains a human web flow at https://iminthebook.com.\n\n## More resources\n\n- Developer documentation: https://iminthebook.com/developers\n- Agent-oriented site summary: https://iminthebook.com/llms.txt\n- Interactive API reference: https://iminthebook.com/docs\n- Questions: help@iminthebook.com\n","version":"1.0.0","contact":{"name":"I'm In The Book Support","email":"help@iminthebook.com","url":"https://iminthebook.com/developers"}},"servers":[{"url":"https://iminthebook.com"}],"paths":{"/api/v1/status":{"get":{"tags":["Public API"],"summary":"Check API availability and discover documentation","description":"Returns the service name, health indicator and public API version, along with pointers to the OpenAPI schema, the developer documentation page and the customer-facing website. Use this as a cheap liveness and discovery probe before calling other endpoints.","operationId":"get_api_status","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatusResponse"}}}},"429":{"description":"Rate limit exceeded. The client sent more than the allowed number of requests in the current window. Inspect the `Retry-After` and `RateLimit` response headers and retry once the window resets.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/pricing":{"get":{"tags":["Public API"],"summary":"List current prices for every product and add-on","description":"Returns the live price list: the hardcover book, the digital book, the gift wrap add-on, an additional hardcover copy of the same book, and the multi-book pricing used when ordering one book per grandchild. Prices are read from the store's pricing configuration on every request, so this endpoint always reflects what a customer would pay right now.","operationId":"get_pricing","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PricingResponse"}}}},"429":{"description":"Rate limit exceeded. The client sent more than the allowed number of requests in the current window. Inspect the `Retry-After` and `RateLimit` response headers and retry once the window resets.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/pricing/quote":{"get":{"tags":["Public API"],"summary":"Calculate an itemized price quote for one book","description":"Calculates what a single book would cost for the given format and add-on selection, returning the same itemized breakdown the website shows at checkout. Promotional and referral discounts are applied during checkout, not here, so the discount field is always 0.00 for public quotes.","operationId":"get_price_quote","parameters":[{"name":"format_type","in":"query","required":false,"schema":{"enum":["hardcover","digital"],"type":"string","description":"Book format to quote: \"hardcover\" for a printed book, \"digital\" for a PDF download.","default":"hardcover","title":"Format Type"},"description":"Book format to quote: \"hardcover\" for a printed book, \"digital\" for a PDF download."},{"name":"gift_wrap","in":"query","required":false,"schema":{"type":"boolean","description":"Set to true to include the gift wrap add-on in the quote.","default":false,"title":"Gift Wrap"},"description":"Set to true to include the gift wrap add-on in the quote."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PriceQuoteResponse"}}}},"429":{"description":"Rate limit exceeded. The client sent more than the allowed number of requests in the current window. Inspect the `Retry-After` and `RateLimit` response headers and retry once the window resets.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/art-styles":{"get":{"tags":["Public API"],"summary":"List the illustration styles a book can be drawn in","description":"Returns every illustration style a customer can choose during book creation. The style applies to the whole book: the same characters are drawn consistently from page to page, just rendered in the chosen look. The `id` values are stable and are what the creation flow stores on an order.","operationId":"list_art_styles","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtStylesResponse"}}}},"429":{"description":"Rate limit exceeded. The client sent more than the allowed number of requests in the current window. Inspect the `Retry-After` and `RateLimit` response headers and retry once the window resets.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/scenes":{"get":{"tags":["Public API"],"summary":"List the selectable story scenes","description":"Returns the catalog of story scenes customers pick from when building a book. Each scene becomes an illustrated page showing the grandchild and a grandparent doing that activity together. Labels are returned with generic placeholders (\"Grandma\" and \"Grandpa\") resolved, because customers can rename grandparents to whatever the family actually uses. Pass `category` to narrow the list.","operationId":"list_scenes","parameters":[{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"enum":["activity","food","funny","sweet"],"type":"string"},{"type":"null"}],"description":"Optional filter. Return only scenes in this category: activities, food, funny moments or sweet moments. Omit to return every scene.","title":"Category"},"description":"Optional filter. Return only scenes in this category: activities, food, funny moments or sweet moments. Omit to return every scene."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScenesResponse"}}}},"429":{"description":"Rate limit exceeded. The client sent more than the allowed number of requests in the current window. Inspect the `Retry-After` and `RateLimit` response headers and retry once the window resets.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/occasions":{"get":{"tags":["Public API"],"summary":"List gift-occasion landing pages","description":"Returns the gift occasions that have a dedicated landing page on the website, each with its page title, summary and absolute URL. Useful for pointing someone at the page that matches why they are shopping.","operationId":"list_occasions","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OccasionsResponse"}}}},"429":{"description":"Rate limit exceeded. The client sent more than the allowed number of requests in the current window. Inspect the `Retry-After` and `RateLimit` response headers and retry once the window resets.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}},"components":{"schemas":{"ArtStyle":{"properties":{"id":{"type":"string","title":"Id","description":"Stable identifier used when creating a book."},"name":{"type":"string","title":"Name","description":"Customer-facing style name."},"description":{"type":"string","title":"Description","description":"One-line description of how the illustrations look."}},"type":"object","required":["id","name","description"],"title":"ArtStyle","description":"One illustration style a customer can choose for their book."},"ArtStylesResponse":{"properties":{"count":{"type":"integer","title":"Count","description":"Number of art styles returned."},"art_styles":{"items":{"$ref":"#/components/schemas/ArtStyle"},"type":"array","title":"Art Styles","description":"The available illustration styles."}},"type":"object","required":["count","art_styles"],"title":"ArtStylesResponse","description":"Every illustration style offered."},"ErrorResponse":{"properties":{"detail":{"type":"string","title":"Detail","description":"Human-readable description of what went wrong."}},"type":"object","required":["detail"],"title":"ErrorResponse","description":"Standard error envelope returned by the public API.","example":{"detail":"Rate limit exceeded. Retry after 42 seconds."}},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"Occasion":{"properties":{"slug":{"type":"string","title":"Slug","description":"URL slug for the occasion page."},"title":{"type":"string","title":"Title","description":"Page title for the occasion."},"description":{"type":"string","title":"Description","description":"Meta description summarizing the occasion page."},"url":{"type":"string","title":"Url","description":"Absolute URL of the occasion landing page."}},"type":"object","required":["slug","title","description","url"],"title":"Occasion","description":"A gift-occasion landing page on the website."},"OccasionsResponse":{"properties":{"occasions":{"items":{"$ref":"#/components/schemas/Occasion"},"type":"array","title":"Occasions","description":"Every published occasion landing page."}},"type":"object","required":["occasions"],"title":"OccasionsResponse","description":"Gift occasions we publish dedicated landing pages for."},"PriceQuoteResponse":{"properties":{"currency":{"type":"string","title":"Currency","description":"ISO 4217 currency code for every amount in this response."},"base_price":{"type":"number","title":"Base Price","description":"Price of the selected book format before add-ons."},"gift_wrap":{"type":"number","title":"Gift Wrap","description":"Gift wrap add-on cost, or 0.0 when not selected."},"discount":{"type":"number","title":"Discount","description":"Discount applied to the quote. Always 0.0 for public quotes; promo codes are applied at checkout."},"total":{"type":"number","title":"Total","description":"Amount payable: base price plus add-ons, minus any discount."}},"type":"object","required":["currency","base_price","gift_wrap","discount","total"],"title":"PriceQuoteResponse","description":"An itemized price quote for one book."},"PricingResponse":{"properties":{"currency":{"type":"string","title":"Currency","description":"ISO 4217 currency code for every price in this response."},"products":{"items":{"$ref":"#/components/schemas/Product"},"type":"array","title":"Products","description":"Every publicly priced product and add-on."}},"type":"object","required":["currency","products"],"title":"PricingResponse","description":"The full public price list, read from the live pricing configuration."},"Product":{"properties":{"id":{"type":"string","title":"Id","description":"Stable identifier for the product or add-on."},"name":{"type":"string","title":"Name","description":"Customer-facing product name."},"price":{"type":"number","title":"Price","description":"Price in the currency given by the parent response."},"description":{"type":"string","title":"Description","description":"Short explanation of what the price covers."}},"type":"object","required":["id","name","price","description"],"title":"Product","description":"A single purchasable product or add-on with its current price."},"Scene":{"properties":{"id":{"type":"string","title":"Id","description":"Stable identifier for the scene."},"label":{"type":"string","title":"Label","description":"Customer-facing label, with grandparent names already resolved."},"category":{"type":"string","title":"Category","description":"Scene grouping: \"activity\", \"food\", \"funny\" or \"sweet\"."}},"type":"object","required":["id","label","category"],"title":"Scene","description":"One selectable story scene."},"ScenesResponse":{"properties":{"count":{"type":"integer","title":"Count","description":"Number of scenes returned after any category filter."},"scenes":{"items":{"$ref":"#/components/schemas/Scene"},"type":"array","title":"Scenes","description":"The selectable story scenes."}},"type":"object","required":["count","scenes"],"title":"ScenesResponse","description":"The catalog of story scenes customers pick from."},"StatusResponse":{"properties":{"service":{"type":"string","title":"Service","description":"Human-readable name of this API service."},"status":{"type":"string","title":"Status","description":"Service health indicator. \"ok\" when the API is serving normally."},"version":{"type":"string","title":"Version","description":"Semantic version of the public API contract."},"docs_url":{"type":"string","title":"Docs Url","description":"Human/agent-readable documentation page for this API."},"openapi_url":{"type":"string","title":"Openapi Url","description":"URL of the OpenAPI 3 schema describing every public endpoint."},"human_site":{"type":"string","title":"Human Site","description":"Root URL of the customer-facing website."}},"type":"object","required":["service","status","version","docs_url","openapi_url","human_site"],"title":"StatusResponse","description":"Service identity and pointers to machine-readable documentation."},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}}}