## Documents

AI-generated professional documents (reports, brochures, catalogs, proposals, CVs, and more) with parallel page generation, design directions, and automatic image enrichment.

### List documents
`GET /documents`
Returns: `{ items: Document[] }`
SDK: `eb.listDocuments()`
MCP: `list_documents`

### Get document
`GET /documents/:id`
Returns: Document with full page/section data.
SDK: `eb.getDocument(id)`
MCP: `get_document({ documentId })`

### Create document
`POST /documents`
Body: `{ name, prompt?, theme?, customColors?, sections? }`
Returns: Document object.
SDK: `eb.createDocument({ name, prompt?, theme?, customColors?, sections? })`
MCP: `create_document({ name, prompt?, theme?, customColors? })`

### Update document
`PATCH /documents/:id`
Body: `{ name?, prompt?, theme?, customColors?, sections? }`
SDK: `eb.updateDocument(id, { name?, prompt?, sections? })`
MCP: `update_document({ documentId, name?, prompt?, theme?, customColors? })` — metadata only; use page tools for content changes

### Delete document
`DELETE /documents/:id`
SDK: `eb.deleteDocument(id)`
MCP: `delete_document({ documentId })`

### Deploy document
`POST /documents/:id/deploy`
Publishes the document as a live website. Requires at least one page.
Returns: `{ url, websiteId, slug }`
SDK: `eb.deployDocument(id)`
MCP: `deploy_document({ documentId })`

### Unpublish document
`POST /documents/:id/unpublish`
Removes the website and reverts to draft status.
SDK: `eb.unpublishDocument(id)`
MCP: `unpublish_document({ documentId })`

### Set page HTML
MCP: `set_page_html({ documentId, pageId, html })`
Updates a single page's full HTML without replacing all pages. Preferred over `update_document` for single-page edits.

### Get page HTML
MCP: `get_page_html({ documentId, pageId })`
Returns the HTML and metadata (id, order, type, name) of a single page.

### Get section HTML (element within a page)
MCP: `get_section_html({ documentId, pageId, cssSelector })`
Returns the outerHTML of a specific element within a page, matched by CSS selector. Examples: `.hero`, `#pricing`, `section:nth-child(2)`, `div.stats`.

### Set section HTML (element within a page)
MCP: `set_section_html({ documentId, pageId, cssSelector, html })`
Replaces a specific element within a page (matched by CSS selector) with new HTML. Enables surgical edits without rewriting the entire page.

### Generate document (AI)
MCP: `generate_document({ documentId, prompt, skipCover? })`
Generates pages with AI via streaming. Use `skipCover: true` to add content pages to an existing document without regenerating the cover.

### Refine section (AI)
MCP: `refine_document_section({ documentId, sectionId, instruction })`
Makes surgical AI-powered changes to a specific page. Returns `{ success, sectionId, htmlLength }` — use `get_page_html` to retrieve the updated content.

### Regenerate page (AI)
MCP: `regenerate_document_page({ documentId, sectionId })`
Completely redesigns a single page while keeping the same content. Returns `{ success, sectionId, htmlLength }` — use `get_page_html` to retrieve the updated content.

### Add page
MCP: `add_page({ documentId, html?, afterPageIndex?, label? })`
Adds a new page to the document. Optionally provide HTML content and insertion position.

### Delete page
MCP: `delete_page({ documentId, pageId })`
Removes a page from the document. Cannot delete the last remaining page.

### Reorder pages
MCP: `reorder_pages({ documentId, pageIds })`
Reorder all pages. `pageIds` must contain every existing page ID exactly once.

### Enhance document prompt (AI)
MCP: `enhance_document_prompt({ name, prompt?, action? })`
SDK: `eb.enhanceDocumentPrompt(name, prompt?)`
Auto-generates a description from the document title (`auto-describe`) or improves an existing prompt with design suggestions (`enhance`).

### Get document directions (AI)
MCP: `get_document_directions({ prompt, pageCount?, sourceContent? })`
SDK: `eb.getDocumentDirections(prompt, { pageCount? })`
Generates 4 design directions (fonts, colors, mood, layout hints). Pass one to `generate_document` via the `direction` parameter.

### PDF to images
MCP: `pdf_to_images({ base64?, fileId?, maxPages? })`
Convert a PDF to PNG images (one per page). Accepts either `base64` (raw PDF in memory — no upload needed) or `fileId` (uploaded PDF). Returns image content items. **To clone a PDF as a document**: (1) `pdf_to_images` to get page images, (2) use vision to generate HTML per page following `get_docs('document-design')` rules, (3) `create_document` with sections.

### Get page screenshot
MCP: `get_page_screenshot({ documentId, pageIndex? })`
Takes a screenshot of a single document page. Returns a PNG image (letter-sized). Page index is 0-based (default 0). Requires Chrome installed locally — designed for Claude Code MCP usage. **Prefer this tool to verify edits visually** after modifying page HTML.

### Document object
```json
{
  "id": "doc123",
  "name": "Q1 Report",
  "prompt": "Quarterly business review for stakeholders",
  "theme": "modern",
  "customColors": { "primary": "#2563eb", "secondary": "#1e40af", "accent": "#f59e0b", "surface": "#ffffff" },
  "sections": [{ "id": "s1", "order": 0, "html": "<section>...</section>", "type": "cover", "name": "Cover" }],
  "status": "DRAFT",
  "pageCount": 5,
  "websiteId": null,
  "createdAt": "2026-03-15T...",
  "updatedAt": "2026-03-15T..."
}
```

### Section/page structure
```json
{
  "id": "section_abc",
  "order": 0,
  "html": "<section class='bg-primary text-on-primary'>...</section>",
  "type": "cover",
  "name": "Cover Page"
}
```

### Design directions
When creating documents from the dashboard, 4 design directions are generated first (fonts, colors, mood, layoutHint). Direction object:
```json
{
  "headingFont": "Playfair Display",
  "bodyFont": "Inter",
  "colors": { "primary": "#2563eb", "secondary": "#1e40af", "accent": "#f59e0b", "surface": "#ffffff" },
  "mood": "professional and clean",
  "layoutHint": "asymmetric with bold headers"
}
```

### Tips for agents
- Use `set_page_html` to update a full page — `update_document` is for metadata only (name, theme, colors).
- Use `add_page` / `delete_page` / `reorder_pages` for page management.
- Use `get_section_html` / `set_section_html` to read/edit a specific element within a page by CSS selector.
- Use `generate_document` with `skipCover: true` to add pages to an existing document.
- Use `refine_document_section` for surgical AI changes — then `get_page_html` to see the result.
- Use `enhance_document_prompt` to improve a prompt before generating.
- Use `get_document_directions` to get 4 design directions, then pass one to `generate_document`.
- Pages use semantic color classes (`bg-primary`, `text-on-surface`, etc.) — changing the theme updates all pages.
- Export to PDF: deploy the document and use `window.print()` or a headless browser on the live URL.

### Workflow
1. `enhance_document_prompt({ name })` — auto-generate a description from the title
2. `get_document_directions({ prompt })` — get 4 design directions
3. `create_document({ name, prompt })` — create a document
4. `generate_document({ documentId, prompt, direction })` — AI generates all pages
5. `refine_document_section({ documentId, sectionId, instruction })` — tweak individual pages
6. `deploy_document({ documentId })` — publish → live URL at `www.easybits.cloud/s/{slug}/`
7. `unpublish_document({ documentId })` — take down when done

### HTML Authoring Guide (for agents writing document HTML)

**Page structure** — every page is a `<section>` with fixed US Letter dimensions:
```html
<section class="w-[8.5in] h-[11in] relative overflow-hidden flex flex-col bg-surface text-on-surface p-12">
  <!-- page content here -->
</section>
```

**ONLY use Tailwind CSS classes — NEVER inline styles.** The FloatingToolbar relies on class-based styling to read and modify elements. Inline styles (`style="..."`) break toolbar editing. The only exception is `font-family` for Google Fonts (via a `<style>` tag or inline on the `<section>`).

**Semantic color classes** (required — these respond to theme changes):
- Backgrounds: `bg-primary`, `bg-secondary`, `bg-accent`, `bg-surface`, `bg-surface-alt`
- Text: `text-on-primary`, `text-on-secondary`, `text-on-accent`, `text-on-surface`, `text-on-surface-muted`
- Borders: `border-primary`, `border-secondary`, `border-accent`, `border-surface`

**Contrast rules**: always pair backgrounds with their matching `text-on-*` class. Example: `bg-primary text-on-primary`, `bg-surface text-on-surface`.

**Google Fonts** — load via `<link>` in a preceding `<style>` block or at the top of the section:
```html
<link href="https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;700&display=swap" rel="stylesheet">
<section style="font-family: 'Playfair Display', serif" class="w-[8.5in] h-[11in] ...">
```

**No responsive breakpoints** — documents are fixed at 8.5×11 inches. Do not use `sm:`, `md:`, `lg:` prefixes.

**Content must fit the page** — never exceed the section dimensions. No scrollbars, no overflow. If content is too long, split it across multiple pages.

**Available themes**: `minimal`, `calido`, `oceano`, `noche`, `bosque`, `rosa`. Each theme defines the semantic color values. Set via `update_document({ theme })` or `customColors` for custom palettes.

**Refine is per-section, not per-page-group** — `refine_document_section` edits a specific element or area within a single section's HTML. Pass `instruction` describing the surgical change (e.g., "change the title to Q2 Report", "make the chart larger") and the current `html` of that section. The AI returns the modified HTML for that section only.

**Images** — use `data-image-query="descriptive search term in English"` on `<img>` tags. The system auto-enriches them with Pexels stock photos:
```html
<img data-image-query="modern office teamwork" class="w-full h-64 object-cover rounded-lg" />
```
