---
name: papergarden
description: Make a printed hardcover picture book with papergarden (MCP or REST). Use when the user wants a picture book, children's book or storybook made or printed.
---

# papergarden: making a picture book

papergarden prints real hardcover picture books (8.5in square, 24-84 pages).
You build the book out of layers, like a designer in Figma: a paper colour,
pictures (mostly full-page scenes, some cut-out vignettes) and text. The
server checks print rules on every write and tells you what to fix.

## Workflow: the words first, then the pictures

Operations (same names over MCP and REST): `get_guide`, `create_book`, `show_book`,
`get_book`, `view_book`, the edit tools (`set_book`, `add_pages`,
`delete_pages`, `move_page`, `duplicate_page`, `set_page`, `add_layers`,
`add_scenes`, `update_layers`, `delete_layers`, `move_layer`,
`copy_layer`, `restore_version`; some clients also have `edit_book`, all
of them in one call), `add_image`, `create_upload_url` (clients with a
shell), `render`, `create_order`, `update_order`, `get_orders`,
`list_books`, `list_images`, `send_feedback`. Without an image model of your own: `generate_image`, `get_image_job`, `cancel_image_job`, `get_credits` (see Pictures). Your client's tool list is what you can call.

Words take seconds to change; pictures take minutes. The user agrees the
text before you make a single picture.

**Rules that always hold:**
- **No sexual content and no graphic gore.** Dark or scary stories are
  fine. Asked for either: say so, and offer a version without it.
- **No deleting books.** papergarden can't delete a book. Asked to delete
  one: say so. Never empty a book (`delete_pages`, `delete_layers`) to
  imitate deleting it. Removing a page or a picture the user wants gone
  while editing is fine. Every version is kept;
  `restore_version` brings one back.
- **Payment happens only on papergarden.ai's checkout page.** Never take
  card details in the chat or pass them anywhere; give the order's
  `checkoutUrl`.
- **View links are read-only.** `view_book` shows the book behind
  /b/<shareToken>; nothing edits a book through its link. Asked to change a
  book from a link: say so, and offer a new book (or `list_books` for the
  user's own books).
- **One picture per page.** There are no pictures across a spread. Asked
  for "pages 2 and 3": a picture on one page and the text on the other, or
  a picture for each. Draw each page as its own picture: never a sheet or
  storyboard of several pages in one image, and no words in a picture (the
  text is a text layer). Asked for many at once, image tools tend to
  return one collage: draw about four pages per batch, each as its own
  image, and carry on with the next batch without asking.
- **Feedback only with the user's say-so.** When the user wants to report
  a problem with papergarden or asks for a feature, offer `send_feedback`
  (signed in): show them the message first, in their words, with nothing
  personal they didn't write. `contact: true` only if they agree to be
  emailed back. Never send feedback on your own.

**What goes in the chat, and what doesn't:**
- Never paste the story text, the picture plan, the bible or prompts into
  the chat. The text goes on the pages, the plan into `notes` and the page
  notes; the user reads them in the book (`show_book` or the view link).
- A chat reply is at most 3 lines, except the interview question.
- When you need a decision, end with 2-4 numbered options ("1. Looks good,
  2. Change something"), so the user can answer with a number.
- Never ask which step comes next or offer to do the next step: do it.
  Stop and wait only at check 1 (text), check 2 (style sample + character
  sheet), check 3 (finished book), and when you need something only the
  user has (a photo, a name, an address).

1. **Interview, in one short message**: who or what the book is about (a
   child, a grandparent, a pet, a favourite toy, a car) and their name, who
   will read it (for a children's book: **their age**), whether they already
   have a story in mind, and, if they like, **a clear reference photo of the
   main character** (and of anyone or anything else that should look like
   itself) so the drawings look like them. The photo is optional: without
   one, ask what the character looks like (hair, colours, glasses, a
   favourite outfit). Most users have a story: a real
   event, a worry, a favourite game, a trip. Then that is the story; your
   job is to tell it well, not to replace it. If they have no idea, don't
   push: write a first try yourself. For a family story, ask what the main
   character calls the people in it (Mum, Papa, Grandad).
2. **Write all the text** with `get_guide` topic `story` (load it now; it
   is not in "all"). Draft, read it critically against that guide, rewrite.
3. **Check 1: the text, as a storyboard.** `create_book` (title, even page
   count 24-84: the story pages plus page 1 and the last page, see Page
   plan) and put each page's text on its page with `add_layers`
   (text, all pages in one call, in a plain spot; you place it properly once the
   picture is in) and the manuscript in its page note. Then `show_book`, or
   give the `viewUrl` if your client shows no widget. In the chat write only
   the title and one line ("24 pages. Read it in the book; tell me what to
   change, or say it's good."). Make changes exactly (`update_layers`), and
   keep the user's words and names. No pictures before they say it's good.
4. **Plan the pictures** (see Pictures) straight after: the bible (age
   included) in `notes` (`set_book`), and each page's plan in its page
   note: the exact text, the picture, the camera, where the text sits, the
   state line. Don't show the plan in the chat; say "Plan ready" in one line.
5. **Check 2: the look.** Make the style sample and the character sheet
   (from the photo, or the description) and show both to the user. This is
   the last question before the pages: wrong here means wrong on every page.
6. **Then make the whole book without stopping to ask**: pictures in page
   order, each checked before it goes in; place each with `add_scenes` or
   `add_layers`, 2-4 spreads per call, and fix every error in `issues`. Then the cover (see
   The cover). Between calls say at most one line ("Pages 1-8 done."). If
   your turn ends before the book is done, carry on in the next one without
   asking.
7. **Review in two passes**: (a) `issues` and `readiness`; (b) `render`
   every spread and compare it with its neighbours against the state lines
   and the bible, then the whole sequence: is a stretch of pages in the
   wrong light, the same camera, the wrong size? Then the cover alone, as a
   picture. Fix what fails; at most two rounds. If you can't see the images
   `render` returns, say so and ask the user to look at the preview.
8. **Check 3: done** only when `readiness.printReady` and
   `readiness.complete`, every warning is fixed or chosen on purpose, and
   you did both review passes. `printReady` alone means nothing: a blank
   book is printable. After an interruption, resume the whole plan. Then
   `show_book` (or the view link) and offer two options: order the
   hardcover (see Ordering), or change something. The user decides.

**Changing a book later** (a new chat): `get_book` and read `notes` and
the page notes first: that is the plan. Change the plan, then the pages, and
keep the notes current. Change the text first and show the user
the changed lines; tell them what it does to the rest of the story before
you draw.

The bookId is the key. A book made while the user is signed in (always,
on papergarden's main MCP address) is theirs; `list_books` finds a
connected user's books (`include: ["cover"]` adds the covers). A book made
without sign-in (where that is allowed) is unclaimed: `get_book` gives a
`links.claim` link for it. With only a view link (`/b/<shareToken>`), `view_book`
reads the pages; it cannot edit and does not show the notes (they stay
private to the bookId).

**A second book with the same characters** (a connected user): `list_images`
lists the pictures of all their books. Reuse the character sheet, the pet
or a favourite toy with `add_image` `assetId` (the new book must be
theirs) instead of drawing it again: the look stays the same. Adding the
same picture twice gives back the asset already in the book.

## Pictures

All art comes from an image model; papergarden does not draw. Image models
copy their references (same pose, same smile, same camera), fill rooms with
clutter and drift towards glossy realism. Everything here works against
those habits.

### The book bible (in the book's notes)

- **Characters and key props**: look, size, clothes for each part of the
  story, and what never changes. A prop the story depends on gets its size
  written down.
- **Places**: a floor plan of every recurring place, seen from the door
  ("bed along the right wall, window above it, lamp to its left"). The
  camera moves; the furniture doesn't.
- **Style**: the medium as visible traits, a palette of 3-5 hex colours,
  the light of each part of the story.
- **Story facts the pictures must not break**: anything the story depends
  on that a picture could contradict ("the sea is far away": no sea in any
  window; "the toy stays at home"). Check every picture against them.
- **Camera**: the book's point of view. Pick the camera that shows the
  story's idea (a small hero's journey is seen from small-hero height).

### State lines

Each page's plan has a state line: what must be visible in this picture
because of the story so far: light, weather, clothes, where people and
things are. Write it as what the picture shows ("the whole kitchen dark
navy, the only light is the torch beam"), not as a fact ("power off").
A state lasts until the story changes it, and it beats the style: a style
with lots of white paper still paints a dark room dark. It applies to every
picture on the page, cut-outs and the page colour included.

### Making the pictures

1. **Style sample**: one small picture in the medium, to agree the look.
2. **Character sheet** per main character, in the style, full body, plain
   background. From a photo, draw the character in the style; after the
   sheet, stop using the photo (it pulls pictures towards realism).
3. **Set plates**: each recurring place, empty, in the style, laid out like
   the bible. They fix the layout, never the camera.
4. **Each page is a new picture.** References: the set plate and the
   character sheet; the previous page only when its state must carry over.
   Never make a page by editing an earlier picture: the pose stays.
5. **Every prompt** has the style sentence (word for word every time), the
   references and what they are for ("only for who she is; do not copy the
   pose"), the action and pose, the expression, the camera, a **Keep** list
   (layout, colours, state line) and a **Change** list (camera, pose,
   action), where the text will go ("top third plain sky, nothing in it"),
   and "no text, no letters".
6. **Compose for the reader's page**: one focal subject and one clear
   action, near the middle with room
   on every side; the strip next to the spine is lost in the fold (see
   Layout). Say what to leave out: plain walls, few objects.
7. **Hold the medium**: describe it by what you can see ("flat matte shapes,
   visible brush edges, dot eyes, flat even light, no gradients").
   Flat, graphic media hold better than loose or detailed ones. A picture
   more realistic or more detailed than the rest is made again.
8. **Vary the camera**: wide, medium and close-up; never the same framing
   on 3 nearby pages (`similar_pictures` warning). Close-ups (a face, two
   hands) carry the feelings, and fewer things must match. Characters act:
   run, hide, reach, sulk; not the same smile at the camera.
9. **Check each picture before it goes in**: state line, bible, the page
   before, a new pose. If not, make it again. A picture fills one page;
   reuse it on a second page only as a deliberate echo
   (`repeated_picture` warning), never as halves across a spread.

### No image model of your own? `generate_image`

If you can't make pictures yourself (Claude, Codex), papergarden makes
them. It needs the user's papergarden account (sign in) and costs image
credits: 1 credit per picture, any size, the cover too (`get_credits`
has the balance and the packs). A refused or
failed picture costs nothing. Out of credits: give the user the buy link
from the error (they pay on papergarden.ai), then carry on.

1. `generate_image` with the full prompt (all of the rules above),
   `references` (assetIds: style sample, character sheets, set plates; say
   in the prompt what each is for, in that order), `page` (the book shows
   the picture being painted there) and a size: 1280x1280 for a page (the
   default), a cut-out with `transparent: true`, 2560x1392 for a
   wraparound cover. It answers at once with a jobId.
2. Start the batch's pictures in a row (up to 10 at once), then call
   `get_image_job` with all their jobIds. It waits up to 45 s and answers
   as soon as one is done; call it again until `allFinished`. No sleep
   needed. Clients with MCP Tasks may run `generate_image` as a task
   instead.
3. A finished picture is already an asset of the book: look at its
   preview, check it (step 9), then place it with `add_scenes`. Not good:
   make it again (that costs again). `cancel_image_job` stops one still
   being made.
4. Only picture-book illustrations: no photographs or photorealism,
   nothing sexual, no gore. Refused prompts say why in the error.

## Layout and type

- **Page plan**: page 1 and the last page sit next to the inside cover of
  the hardcover. **Page 1 is the title or dedication page** (the title, "For
  Mila", a small line); **the story starts on page 2-3** (the first spread);
  **the last page is left free or holds "The End"**. The server refuses a
  picture, or text over 25 words, on page 1 or the last page unless the edit
  says `useReservedPage: true` (in the layer for `add_layers`, on the
  scene for `add_scenes`, or in `update_layers` `set`). Use it only for a deliberate
  exception, e.g. a small vignette under the title; never to fit the story.
- **Most story pages are full-page scenes**, placed with
  `add_scenes`: the server fills the page and centres the picture on the part the
  reader sees. A 1254px square picture is big enough. Never shrink a scene
  into the margins with a border of paper (`boxed_picture` warning).
- **A close-up is a full-page picture too**: the face, the hands or the
  wet mouse fill the page. A small cut-out with white paper around it reads
  as unfinished, not intimate.
- **Vignettes** (a transparent cut-out on the paper colour) only for a
  deliberate quiet beat, or under the title on page 1 or by "The End" (with
  `useReservedPage: true`): rarely, 300-450pt wide,
  centred on the visible page. Ask for "isolated on a transparent
  background, no ground, no shadow"; an opaque one becomes a scene.
- **The fold**: every page loses a strip one margin wide (36pt) at the
  spine into the binding. Centre text and vignettes on what is left (x 333
  on odd pages, x 297 on even pages), and keep text 1in from the trim at
  the spine (`text_in_gutter` error). `render` shows pages without that
  strip.
- **Text sits in a calm part of the picture** that the prompt kept empty:
  never over faces, hands or detail. Every page gets its own text position.
  The server warns about `text_low_contrast` and `text_on_busy_area`.
- **Text hard to read on a finished picture?** First move it to a calmer
  spot. If there is none, give the text layer a `background` (`update_layers`
  `set`): that is cheaper and safer than making the picture again, so
  prefer it to regenerating. Pick one preset for the whole book and keep it:
  - soft cream fade: `{ "color": "#FFF8EC", "opacity": 0.85, "padding": 28, "edge": "soft" }`
    (a glow behind the words; the default choice for painted scenes)
  - rounded card: `{ "color": "#FFFFFF", "opacity": 0.9, "padding": 14, "radius": 14 }`
    (a crisp label; good for comics and graphic styles)
  - subtle band: `{ "color": "#FFF8EC", "opacity": 0.7, "padding": 20, "edge": "soft" }`
    on a frame as wide as the text area (x 81..585 on odd pages, 45..549 on
    even ones), a quiet strip
  For light text (#FFF8EC) on dark art use a dark colour, e.g. `"#2B2B2B"`
  at 0.6. Keep backgrounds the exception, not on every page.
- **Type**: one story font (18-26pt), optionally a display font for the
  title (48-90pt); lines under ~45 characters; dark text on light areas,
  light (#FFF8EC) on dark. Line breaks follow the sense, or the verse
  (`\n`); never one word alone on the last line (`text_orphan`).
- **Rhythm across spreads**: wide scenes, close-ups, vignettes, a quiet
  page, one big full-page moment for the climax.
- **Paper colour**: one book colour (`set_book` `background`); a page
  override (`set_page` `background`) only on purpose.
- **Comics**, when asked for: panels are image layers with `stroke` in a
  grid with 12-18pt gutters; speech is a `bubble` shape whose `tail`
  points at the speaker, with a text layer inside, off faces, in reading
  order.

## The cover

- **Make it last**, with **its own picture composed for the cover**: the
  child doing the book's key thing, a calm area kept for the title, nothing
  important near the edges. Never crop a page picture onto it.
- The front the reader sees is x 693..1323, y 45..693; the title and faces
  go inside the **front safe area x 738..1278, y 90..648**, with 20pt of air.
- Either a vignette (350-500pt) on the cover colour, or a picture filling
  the front panel (x 738 to past 1368, y past 0 to past 738, `bleed: true`,
  a full-page picture). Not an opaque box floating on the cover
  (`boxed_picture`). The title big, in a display font, on a calm area.
- The back (x 90..630): the cover colour, one short line or a small
  vignette. A picture across the whole wrap needs ~2600px; models don't
  make that.
- **Review it as a picture**: `render` `{ "pages": ["cover"] }`. Does it
  show the child and the story? Is anything cut awkwardly? Is the title
  readable as a thumbnail?

## Geometry and reference (points, 72pt = 1in, origin top-left)

- Page: **630 x 630**, of which the outer 9pt is bleed. **Safe area x
  45..585, y 45..585**: all text and everything important. A layer may run
  off the page only with `bleed: true`, and each edge then goes past the
  sheet edge or stays inside the safe area.
- Page 1 is a right-hand page; then spreads 2+3, 4+5, ... Odd pages have the
  spine on the left, even pages on the right. Page 1 and the last page are
  reserved (title, dedication, "The End"; see Page plan). Each page loses 36pt at the
  spine: the reader sees x 45..621 (odd) or x 9..585 (even). Text at
  x >= 81 (odd) or x + width <= 549 (even).
- Cover: one 1368 x 738 sheet, back | spine | front. Front safe area x
  738..1278, back x 90..630, y 90..648. Spine x 675..693 and the outer 45pt
  are keep-out zones.
- Text always renders above images and shapes.

### Editing

Every edit tool takes `bookId` and `baseVersion` (the version you last
saw) and makes one new version: all of the call applies or none.
`version_conflict`: `get_book`, then redo. One exception: an edit that
only changes the words of text layers (`update_layers` with just `text`)
goes on top of a newer version when nobody changed those words since; its
`adjustments` say so. The book's owner can also edit the words by hand on
the book page: such versions say "(by the book's owner, on the website)".
Keep their words unless they ask otherwise. `surface` is `"cover"` or a
1-based page number. Tools that add layers return their `layerIds`.
Every version is kept; `restore_version` undoes. Smallest layers: pictures
and text frames 9pt wide (a picture also at least 1pt high), text 6pt
high, shapes 1pt.

| tool | fields (besides bookId, baseVersion) |
|---|---|
| `set_book` | `title?`, `notes?`, `background?` |
| `add_pages` | `count`, `after?` (0 = start) |
| `delete_pages` | `pages` |
| `move_page` | `from`, `to` |
| `duplicate_page` | `page` |
| `set_page` | `surface`, `background?` (null = follow book), `note?` |
| `add_scenes` | `scenes`: [{ `page`, `assetId`, `flipX?`, `crop?`, `useReservedPage?` }] |
| `add_layers` | `layers`: [{ `surface`, `layer`, `index?` }] |
| `update_layers` | `changes`: [{ `layerId`, `set` }] |
| `delete_layers` | `layerIds` |
| `move_layer` | `layerId`, `to` ("front", "back" or index), `surface?` |
| `copy_layer` | `layerId`, `surface`, `x?`, `y?` |
| `restore_version` | `version` |

```json
{ "bookId": "bk_…", "baseVersion": 3, "layers": [
  { "surface": 2,
    "layer": { "type": "text", "text": "Mila had a red umbrella.", "x": 70, "y": 70, "width": 420, "size": 24 } },
  { "surface": 3,
    "layer": { "type": "image", "assetId": "as_mila_jumping", "x": 150, "y": 110, "width": 380 } }
] }
```

`edit_book` (where your client has it) takes the same operations as a list
of `ops` (`{ "op": "add_layer", ...one layer }`, `add_scene`,
`update_layer`, `delete_layer`, `set_surface`, `restore`, and the
names above), applied in order in one call; `ref` names a new layer for
later ops in the same call.

### Images

`add_image` takes exactly one source: `url` (public https); `uploadId`;
`base64` (up to about 7 MB); or `image` (a ChatGPT file reference). PNG or
JPEG only (no WebP), up to 25 MB and 16 megapixels; PNGs up to about 2700x2700.
Phone photos are turned upright by their EXIF orientation. With a shell (Codex, Claude
Code), call `create_upload_url` once with `count`, then PUT each file with
a label: `curl -sS -X PUT --data-binary @mila.png -H "Content-Type: image/png" "<uploadUrl>?label=Mila%20jumping"`;
the response is the asset. It returns `width`, `height` and `hasAlpha`
(opaque = a scene for `add_scenes`, transparent = a cut-out). Image
layers take `x`, `y`, `width` (height
follows), `crop` (fractions), `flipX`, `mask` ("ellipse", "rounded"),
`stroke`/`strokeWidth`, `useReservedPage` (page 1 or the last page on
purpose).

### Text layers

`text`, `x`, `y`, `width`, `height?` (leave it out to fit), `font?`,
`size?`, `weight?`, `color?`, `align?`, `valign?`, `lineHeight?`,
`letterSpacing?`, `background?` (`color`, `opacity?` 0.85, `padding?`
0-36pt, `radius?`, `edge?` "hard" or "soft"; `null` in `set` removes it),
`useReservedPage?`. Markup: `**bold**`, `[word]{#C0392B}`, `\n`. Fonts:
`andika` (default, early-reader sans), `nunito`, `quicksand`, `literata`
(warm serif), `fraunces` (display serif), `fredoka` (chunky display),
`patrick-hand`. Errors: `text_overflow` (frame too short), `text_too_wide`
(a word wider than the frame), `missing_glyphs` (the font has no glyph for
a letter: it names a font that has it), `font_unavailable` (the server
could not load a script font just now: retry later, nothing to change).
Fonts by language:
- all fonts: English, Dutch, German, French, Spanish, Italian, Portuguese, Danish, Norwegian, Swedish, Finnish, Icelandic, Afrikaans, Catalan, Basque, Galician, Frisian, Irish, Luxembourgish, Albanian, Indonesian, Malay, Swahili, Estonian, Filipino, Cebuano, Javanese, Sundanese, Zulu, Xhosa, Somali, Oromo, Kinyarwanda, Malagasy, Shona, Haitian Creole, Scottish Gaelic, Simplified Chinese, Traditional Chinese, Cantonese, Japanese, Korean, Hindi, Marathi, Nepali, Bengali, Assamese, Punjabi, Gujarati, Odia, Tamil, Telugu, Kannada, Malayalam, Sinhala, Thai, Lao, Khmer, Burmese, Arabic, Persian, Urdu, Pashto, Sorani Kurdish, Hebrew, Yiddish, Amharic, Tigrinya, Georgian, Armenian.
- `andika`, `nunito`, `quicksand`, `literata`, `fraunces`, `patrick-hand`: Polish, Czech, Slovak, Hungarian, Romanian, Croatian, Slovenian, Bosnian, Serbian Latin, Latvian, Lithuanian, Turkish, Maltese, Welsh, Vietnamese, Wolof, Chichewa, Kurmanji Kurdish, Māori, Esperanto.
- `andika`, `nunito`, `quicksand`, `literata`, `fraunces`: Azerbaijani.
- `andika`, `nunito`, `literata`: Russian, Ukrainian, Belarusian, Bulgarian, Serbian Cyrillic, Macedonian, Kazakh, Kyrgyz, Mongolian.
- `literata`: Greek.
- `andika`, `nunito`, `quicksand`, `literata`: Uzbek, Igbo.
- `andika`: Hausa, Yoruba, Lingala, Twi.
- `andika`, `nunito`: Fula, Tajik.

Other scripts need no setting. The book font draws Latin letters, digits
and punctuation; Chinese (Simplified), Chinese (Traditional), Japanese, Korean, Arabic script, Hebrew, Devanagari, Bengali, Gurmukhi, Gujarati, Odia, Tamil, Telugu, Kannada, Malayalam, Sinhala, Thai, Lao, Khmer, Burmese, Georgian, Armenian and Ethiopic letters print in a matching Noto font, picked from
the letters (Chinese: Simplified unless the text has Traditional-only
characters; with kana it is Japanese). Right-to-left text (Arabic,
Hebrew, Persian, Urdu) is detected from its first letter: it runs right to
left and `align` "left"/"right" mean the start/end of the line (start =
right). Chinese and Japanese lines break between characters (never before
。、」 or small kana), Thai, Lao, Khmer and Burmese between words, Korean at
spaces. New text in tall scripts gets a larger `lineHeight` (up to 2).

## Ordering

A printed hardcover costs **€39 per copy + shipping** (VAT included).
Only a person pays; you do everything else.

1. `create_order` with `bookId` and `baseVersion` (the version the user
   approved). It runs the print check: `ready: false` + `issues` means fix
   those first. Later edits don't change an order.
2. Ask the user, one thing at a time, and pass it with `update_order`:
   their **email**, the **shipping address** (name, line1, city, postcode,
   country ISO-2, phone; the recipient can be someone else, e.g. a gift),
   then the **shipping speed** from `shippingOptions` (each with price and
   delivery estimate). `quantity` for more copies.
3. When `missing` is empty the order has `checkoutUrl`: the order page on
   papergarden.ai. Show the total (`price.display`) and give the link as
   a plain link, with no picture of the book. Stop there: the user checks the order there and presses Pay, which opens
   Stripe's payment page. The link is safe to forward (say, to a grandparent
   who pays); the `orderId` is not: it changes the order, so never show it.
   The link keeps working; if the order shows `draft` with nothing missing,
   call `update_order` with just the `orderId`.
4. `get_orders` shows status (paid → sent_to_printer → printing → shipped;
   or needs_attention, refunded), tracking and any `problem` (tell the user
   its message and fix). `orderUrl` is the user's page to follow the order.
   To order another copy, `create_order` again.

**Where we ship:** 215 countries and territories, every one our
printer delivers to. Not to: Afghanistan (AF), Belarus (BY), Central African Republic (CF), Cuba (CU), Western Sahara (EH), Falkland Islands (Islas Malvinas) (FK), Equatorial Guinea (GQ), Guinea-Bissau (GW), Heard & McDonald Islands (HM), Iran (IR), Kiribati (KI), Comoros (KM), North Korea (KP), Myanmar (Burma) (MM), Nauru (NR), Niue (NU), St. Pierre & Miquelon (PM), Russia (RU), Solomon Islands (SB), Sudan (SD), St. Helena (SH), Sierra Leone (SL), Somalia (SO), South Sudan (SS), São Tomé & Príncipe (ST), Syria (SY), Tajikistan (TJ), Tokelau (TK), Turkmenistan (TM), Tuvalu (TV), Ukraine (UA), U.S. Outlying Islands (UM), Venezuela (VE), Yemen (YE).
Some countries need more in the address: `state` for
AE, AU, BR, CA, CN, CO, CR, ES, HN, ID, IN, IQ, IT, JM, JP, KN, KR, MX, PG, SV, TW, US (its ISO 3166-2 code
without the country part, or its name: "CA" or "California", "13" or
"Tokyo"); `taxId`, the recipient's tax ID, for Brazil (CPF / CNPJ), Chile (RUT), and Mexico (RFC), because customs there require it. Outside the EU, customs
duties or import taxes may be charged on delivery and the recipient pays
them: tell the user when the address is outside the EU.
Where the country has no postcodes (e.g. Hong Kong, the United Arab
Emirates, Qatar; 55 in all, listed in the `postcode` field), leave `postcode` out.

Address errors come back per field (`path: "shippingAddress.postcode"`)
with a `fix`: ask the user for exactly that. The printer also checks the
address: if it suggests a corrected one, the order has `addressSuggestion`
and `missing` contains `addressCheck`. Show both versions to the user and
call `update_order` with `acceptSuggestion: true` or `keepAddress: true`.
Until then the order is `draft`, with no `checkoutUrl`.

**The book changed after the order started?** The order then has
`bookChange` (what changed, when). Nothing moves by itself: unless
`bookChange.kept` is true, ask the user which to print, the book as it
is now or the version from when they ordered, and pass their choice with
`update_order` `printVersion: "current"` or `"ordered"`. Don't choose
for them. The payment page asks too until someone chooses.

## Connect

- **MCP** (Streamable HTTP, sign-in required): `https://papergarden.ai/mcp`
  - Codex: `codex mcp add papergarden --url https://papergarden.ai/mcp`
  - Claude Code: `claude mcp add --transport http papergarden https://papergarden.ai/mcp`
  - Without a token every request is HTTP 401 with
    `WWW-Authenticate: Bearer resource_metadata="https://papergarden.ai/.well-known/oauth-protected-resource"`:
    your client then signs the user in (OAuth 2.1, free account, email) and retries.
- **REST**: `https://papergarden.ai/api/v1`, OpenAPI at `https://papergarden.ai/api/v1/openapi.json`.
  JSON in, JSON out. Errors: HTTP status + `{"error": {"code", "message", "fix", "path", "retryable"}}`.
  `version_conflict` is 409, `invalid_input` is 422.
- **Sign-in**: required on MCP. On REST optional, except for `list_books`, `get_orders` without ids,
  `send_feedback`, and papergarden's own pictures: `generate_image`, `get_image_job`, `cancel_image_job`,
  `get_credits`. OAuth 2.1 authorization code + PKCE, `Authorization: Bearer <token>`. See
  `components.securitySchemes` in openapi.json and
  `https://papergarden.ai/.well-known/oauth-authorization-server/api/auth`.

Operations (identical over MCP and REST):

- `get_guide`: GET /api/v1/guide. How to make a papergarden book: workflow, story, pictures, layout, the cover, geometry and reference. Read topic "all" once before making a book.
- `create_book`: POST /api/v1/books. 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.
- `show_book`: GET /api/v1/books/{bookId}/show. Open the book in the chat as an interactive widget (pages, print status and an Order button). Call it once after create_book so the user can watch; it refreshes itself when you edit. Other clients get the view link.
- `get_book`: GET /api/v1/books/{bookId}. 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.
- `view_book`: GET /api/v1/shared/{shareToken}. 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: nothing can change a book through its view link. Asked to edit a book from a link: say so, and offer to make a new book (or list_books for the user's own).
- `set_book`: POST /api/v1/books/{bookId}/edits/set_book. Change the book's title, its notes (your plan: manuscript, style, characters) or its paper colour. Replaces the old value. Every version is kept: restore_version brings the old one back. Send baseVersion = the version you last saw. Returns the new version and the print issues on the pages it touched.
- `add_pages`: POST /api/v1/books/{bookId}/edits/add_pages. Add blank pages to a book, at the end or after a given page. Only adds pages; later pages get new numbers. Send baseVersion = the version you last saw. Returns the new version and the print issues on the pages it touched.
- `delete_pages`: POST /api/v1/books/{bookId}/edits/delete_pages. Remove pages from a book (never the whole book: papergarden can't delete books). Never use it to empty a book because the user asked to delete it. Every version is kept: restore_version brings the old one back. Send baseVersion = the version you last saw. Returns the new version and the print issues on the pages it touched.
- `move_page`: POST /api/v1/books/{bookId}/edits/move_page. Move one page to another position in the book. If the page moves to the other side of the spread, full-page pictures are placed for that side. Every version is kept: restore_version brings the old one back. Send baseVersion = the version you last saw. Returns the new version and the print issues on the pages it touched.
- `duplicate_page`: POST /api/v1/books/{bookId}/edits/duplicate_page. Copy a page with everything on it; the copy goes right after it. Only adds a page. Send baseVersion = the version you last saw. Returns the new version and the print issues on the pages it touched.
- `set_page`: POST /api/v1/books/{bookId}/edits/set_page. Give a page or the cover its own paper colour (null = follow the book colour again) and set your note for it (e.g. its manuscript text and picture plan). Replaces the old value. Every version is kept: restore_version brings the old one back. Send baseVersion = the version you last saw. Returns the new version and the print issues on the pages it touched.
- `add_layers`: POST /api/v1/books/{bookId}/edits/add_layers. Add layers to pages or the cover: text, a picture (an asset from add_image) or a shape. 1-100 in one call, e.g. the text of every page at once. Each is checked against the print rules. For a full-page picture use add_scenes. Only adds. Send baseVersion = the version you last saw. Returns the new version and the print issues on the pages it touched.
- `add_scenes`: POST /api/v1/books/{bookId}/edits/add_scenes. Put full-page pictures (scenes) on pages: 1-50 in one call. A full-page picture (a scene) on a page, placed by the server: edge to edge with bleed, centred on the part of the page the reader sees (shifted 18pt away from the spine, so the strip lost in the fold is the picture's own edge). It goes behind the other layers. If pages later move to the other side of the spread, the server mirrors the placement. Only adds: a page's earlier picture stays until you remove it with delete_layers. Send baseVersion = the version you last saw. Returns the new version and the print issues on the pages it touched.
- `update_layers`: POST /api/v1/books/{bookId}/edits/update_layers. Change existing layers: the words, position, size, font, colours, crop, mask and more. 1-100 changes in one call. Only the fields in set change; they replace the old values. Every version is kept: restore_version brings the old one back. Send baseVersion = the version you last saw. Returns the new version and the print issues on the pages it touched.
- `delete_layers`: POST /api/v1/books/{bookId}/edits/delete_layers. Remove layers from pages or the cover, e.g. a picture you're replacing. 1-100 in one call. Never use it to empty a book because the user asked to delete it. Every version is kept: restore_version brings the old one back. Send baseVersion = the version you last saw. Returns the new version and the print issues on the pages it touched.
- `move_layer`: POST /api/v1/books/{bookId}/edits/move_layer. Move a layer to the front or back (or a stack position), or to another page or the cover (same x, y). Every version is kept: restore_version brings the old one back. Send baseVersion = the version you last saw. Returns the new version and the print issues on the pages it touched.
- `copy_layer`: POST /api/v1/books/{bookId}/edits/copy_layer. Copy a layer to a page or the cover, at the same or a new x, y. Only adds. Send baseVersion = the version you last saw. Returns the new version and the print issues on the pages it touched.
- `restore_version`: POST /api/v1/books/{bookId}/edits/restore_version. Make the book look like an earlier version again (undo). This makes a new version, so nothing is lost: the version before the restore can be restored too. Every version is kept: restore_version brings the old one back. Send baseVersion = the version you last saw. Returns the new version and the print issues on the pages it touched.
- `edit_book`: POST /api/v1/books/{bookId}/edits. Apply a batch of mixed ops to one book in one call: the same operations as the single edit tools (set_book, add_pages, add_layers, update_layers, ...), all or none, one new version. For agents that lay out many pages at once. A layerId in an op can also be a ref set by an earlier op in the same call. Send baseVersion = the version you last saw. Returns print issues for the surfaces you touched. Every version is kept: restore brings any of them back.
- `add_image`: POST /api/v1/books/{bookId}/assets. Turn a picture into a book asset (does not place it; place it with add_scenes or add_layers). Give exactly one source: url, image (a ChatGPT file), base64, uploadId (clients with a shell: create_upload_url), or assetId (a picture from the signed-in user's library, see list_images). PNG or JPEG (no WebP). Prefer transparent PNG cut-outs. The same picture twice gives the asset already there. Returns size, transparency, max sharp print width and a preview.
- `generate_image`: POST /api/v1/books/{bookId}/image-jobs. Make a picture-book illustration with papergarden's image model, for assistants that can't make pictures themselves (if you can, make it yourself and use add_image). Needs the user's papergarden account and costs image credits (get_credits): 1 credit per picture, any size (a page, a cut-out or the cover). Credits are kept only for a picture actually delivered; a refused or failed picture costs nothing. Returns at once with a jobId; the picture takes about 30-120 s. Start every page's picture in a row, then call get_image_job with all the jobIds: it waits for them. Done pictures are already book assets: place them with add_scenes (full page) or add_layers. Sizes (width x height, multiples of 16, up to 4.2 megapixels): a page 1280x1280 (the default), a cut-out any shape (transparent: true), a wraparound cover 2560x1392. Picture-book illustrations only: no photographs or photorealism, nothing sexual, no gore.
- `get_image_job`: POST /api/v1/image-jobs/check. How the pictures started with generate_image are doing. Waits up to waitSeconds (default 30, at most 45) and answers as soon as one of them is done, so call it again and again until allFinished; no sleep needed in between. Done: the picture is a book asset (place it with add_scenes or add_layers) and a small preview is attached to look at. Failed or cancelled: error.fix says what to do; its image credits went back. Without jobIds: the user's newest 20 (of bookId, if given).
- `cancel_image_job`: POST /api/v1/image-jobs/{jobId}/cancel. Stop a picture that is still being made (generate_image); its image credits go back. A finished picture stays (it is an asset of the book).
- `get_credits`: GET /api/v1/credits. The signed-in user's image credits for generate_image, what a picture costs, the packs for sale and buyUrl: the papergarden.ai page where the user buys more (only the user pays; never open it for them).
- `create_upload_url`: POST /api/v1/books/{bookId}/uploads. 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.
- `render`: POST /api/v1/books/{bookId}/renders. A picture (JPEG) of pages, a spread or the whole book as a contact sheet, as the reader will see it: pages trimmed, the fold shaded on the spine side, the cover with its wrap folded away. Use it to judge your layout like an art director. guides: true shows the whole print sheet instead, with trim (red), safe area (green), the fold band next to the spine (amber) and the cover wrap (shaded).
- `create_order`: POST /api/v1/orders. 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). A book has at most one unpaid order: calling this again reuses it as it is; if the book changed since, it has bookChange (ask the user which version to print). €39 per copy + shipping.
- `update_order`: PATCH /api/v1/orders/{orderId}. 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. When the order has bookChange, printVersion records the user's choice of version. Same input twice gives the same order.
- `get_orders`: GET /api/v1/orders. One order (orderId) or all orders of a book (bookId): status, price, payment link, tracking, problems. Read-only.
- `list_books`: GET /api/v1/books. The signed-in user's books across chats (needs the papergarden account connected). Anonymous books appear here once the user claims them. include ["cover"] adds each cover.
- `list_images`: GET /api/v1/images. The signed-in user's picture library: every picture made for their books (character sheets, the family dog, a favourite toy), newest first, up to 500. Use one in another book with add_image's assetId instead of drawing it again. Needs the user's account. Read-only.
- `send_feedback`: POST /api/v1/feedback. Send the papergarden team a problem report or a feature idea, in the user's words. Use it only when the user asks to report a bug or request a feature (or agrees when you offer it), and never without their say-so: show them what you will send first. Write the message from what the user said (what they did, what happened, what they expected); add no personal data they didn't write themselves (no names, addresses or emails). Add bookId or orderId if it's about one of their books or orders. contact: true only if the user agrees to be emailed back about it. Needs the user's papergarden account. Only adds: changes no book or order.

REST example:

```sh
curl -s -X POST https://papergarden.ai/api/v1/books -H 'content-type: application/json' -d '{"title":"Mila and the Rain"}'
curl -s -X POST https://papergarden.ai/api/v1/books/<bookId>/uploads -H 'content-type: application/json' -d '{"count":2}'   # → uploads[].uploadUrl
curl -s -X PUT --data-binary @mila.png -H 'content-type: image/png' "<uploadUrl>?label=Mila"             # → the new asset
curl -s -X POST https://papergarden.ai/api/v1/books/<bookId>/edits -H 'content-type: application/json' -d '{"baseVersion":1,"ops":[...]}'
# papergarden draws (signed in, image credits): start, then wait for it
curl -s -X POST https://papergarden.ai/api/v1/books/<bookId>/image-jobs -H "authorization: Bearer $TOKEN" -H 'content-type: application/json' -d '{"label":"Mila jumping","prompt":"..."}'   # → jobId
curl -s -X POST https://papergarden.ai/api/v1/image-jobs/check -H "authorization: Bearer $TOKEN" -H 'content-type: application/json' -d '{"jobIds":["<jobId>"],"waitSeconds":45}'   # → jobs[].asset when done
```
