> ## Documentation Index
> Fetch the complete documentation index at: https://docs.blinkpdf.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Headers, Footers & Page Numbers in PDF Renders

> Add running headers, footers, page numbers, section-driven fragments, divider rules, per-page overrides, and optional decorative watermarks using the furniture field on POST /v1/render.

Blink PDF lets you define running headers and footers that repeat on every page of your rendered document. You configure them through the `furniture` object of your `POST /v1/render` request body — no templates to host, no HTML to write. Headers and footers are built from ordered **fragments**: static text, page numbers, document metadata, running section titles, and section ordinals derived from your Markdown headings.

<Note>
  The fields below are validated against the live API schema. The **API Reference → Render** endpoint is generated directly from the server's OpenAPI contract and is always the authoritative source for every field and constraint.
</Note>

## How `furniture` Works

Page furniture is organized into six **slots** — one for each corner and center of the top and bottom edges:

|                     | Left         | Center         | Right         |
| ------------------- | ------------ | -------------- | ------------- |
| **Top (header)**    | `topLeft`    | `topCenter`    | `topRight`    |
| **Bottom (footer)** | `bottomLeft` | `bottomCenter` | `bottomRight` |

Each slot holds an ordered list of **content fragments**:

| `kind`          | Renders                                                       | Notes                                                                                                             |
| --------------- | ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| `text`          | The literal string in `value`                                 | Optional per-fragment `style` (font slot, size, color, opacity)                                                   |
| `image`         | An image (e.g. a header/footer logo)                          | Sourced from a `data:` URI, an `http(s)://` URL, or a [`blink://asset/<id>`](/concepts/markdown-rendering) handle |
| `pageNumber`    | The current page number                                       |                                                                                                                   |
| `totalPages`    | The total number of pages                                     |                                                                                                                   |
| `documentTitle` | `metadata.title`, or the title derived from the first heading |                                                                                                                   |
| `sectionTitle`  | The running section title at a heading `depth` (1–6)          |                                                                                                                   |
| `sectionIndex`  | The section ordinal at a heading `depth` (1–6)                | Use `format`: `twoDigit` (01, 12; ≥100 renders in full) or `decimal` (1, 2, …)                                    |

Fragments in a slot are concatenated in order. A "Page 3 of 12" footer is four fragments: `text` → `pageNumber` → `text` → `totalPages`. A magazine-style header might combine `sectionIndex` and `sectionTitle` at `depth: 1`.

<Note>
  A fragment that can only ever render empty — a `sectionTitle`/`sectionIndex` at a heading `depth` the document never reaches, or a `documentTitle` when no title resolves — is flagged by `validate_render_pdf` as `furniture_fragment_empty` so you can fix or drop it.
</Note>

## The `furniture` Object

<ParamField body="furniture" type="object">
  Running headers and footers. `slots` applies to every page; set `omitFirstPage: true` to suppress furniture on the cover page only, or pass `firstPage` to override the first page. Set `omitLastPage: true` to suppress furniture on the closing page (when `totalPages` > 1), or pass `lastPage` to override the final page. Optional `pageOverrides` supplies arbitrary per-page exceptions. Optional `decorations` draws header/footer divider rules. Optional `watermark` draws faint text behind body content.

  <Expandable title="furniture fields">
    <ParamField body="furniture.slots" type="object">
      Content for each of the six positions. Each key (`topLeft`, `topCenter`, `topRight`, `bottomLeft`, `bottomCenter`, `bottomRight`) is optional and takes a `content` array of fragments (1–16 per slot) and an optional slot-level `style`.
    </ParamField>

    <ParamField body="furniture.omitFirstPage" type="boolean">
      When `true`, suppresses all furniture on the first page only — including `watermark` and `decorations`. Use this for cover pages while keeping headers and footers on every following page.
    </ParamField>

    <ParamField body="furniture.firstPage" type="object">
      A first-page-only override of `slots` with the same six-slot shape. Use when the cover should show different furniture than the rest, not when you want a blank first page (use `omitFirstPage` instead).
    </ParamField>

    <ParamField body="furniture.omitLastPage" type="boolean">
      When `true`, suppresses all furniture on the final page only — including `watermark` and `decorations`. Ignored when the document has only one page. Use this for signature or closing pages while keeping headers and footers on every preceding page.
    </ParamField>

    <ParamField body="furniture.lastPage" type="object">
      A last-page-only override of `slots` with the same six-slot shape. Use when the closing page should show different furniture than the rest, not when you want a blank final page (use `omitLastPage` instead).
    </ParamField>

    <ParamField body="furniture.inset" type="object">
      Distance of the furniture from the page edges, in points. Accepts `top` (header distance from the top edge) and `bottom` (footer distance from the bottom edge).
    </ParamField>

    <ParamField body="furniture.decorations" type="object[]">
      Non-text margin graphics composed alongside the six-slot grid (up to 8 entries). Each item is a `rule` — a horizontal hairline in a header or footer band.

      <Expandable title="decoration fields">
        <ParamField body="kind" type="string" required>
          Must be `rule`.
        </ParamField>

        <ParamField body="band" type="string" required>
          `header` or `footer` — which margin band carries the rule.
        </ParamField>

        <ParamField body="placement" type="string" required>
          `inner` draws toward the body: below header text or above footer text.
        </ParamField>

        <ParamField body="style" type="object">
          Stroke overrides. Omitted fields fall back to defaults (0.5 pt hairline, 6 pt offset). Accepts `color` (`#RGB` or `#RRGGBB`), `width` (0.1–50 pt), `opacity` (0–1), `dash` (`[dash, gap]` in points), `inset` (horizontal inset from each content edge), `offset` (vertical gap between band text and the rule), and `lineCap` (`butt`, `round`, `projecting`).
        </ParamField>
      </Expandable>
    </ParamField>

    <ParamField body="furniture.pageOverrides" type="object[]">
      Arbitrary per-page furniture exceptions (up to 64 entries). Later matching entries win per field. Cover/closing sugar (`omitFirstPage`, `firstPage`, `omitLastPage`, `lastPage`) applies after overrides on pages 1 and the final page.

      <Expandable title="pageOverrides entry fields">
        <ParamField body="match" type="object" required>
          Selects which pages the override applies to. Use exactly one of:

          * `pageIndex` — zero-based page index (same coordinate as the renderer's `pageIndex`)
          * `pageNumber` — one-based page number
          * `sectionStarts` — matches pages where a heading at `depth` (1–6) begins; optionally filter with `textEquals` (exact heading plaintext, 1–512 characters)
        </ParamField>

        <ParamField body="slots" type="object">
          Per-page slot overrides with the same six-slot shape as `furniture.slots`.
        </ParamField>

        <ParamField body="watermark" type="object | null">
          Per-page watermark override, or `null` to suppress the default watermark on matching pages.
        </ParamField>

        <ParamField body="decorations" type="object[] | null">
          Per-page decoration list replacing the default list on matching pages, or `null` to suppress default decorations.
        </ParamField>

        <ParamField body="omit" type="boolean">
          When `true`, suppresses all furniture on matching pages (slots, watermark, and decorations). Do not combine with `slots`, `watermark`, or `decorations`.
        </ParamField>
      </Expandable>
    </ParamField>

    <ParamField body="furniture.watermark" type="object">
      Decorative watermark drawn **behind** body content on every page (distinct from the [Free-plan billing mark](/help/troubleshooting#watermark-appearing-on-pdfs)). Either static `text` (1–256 characters) or per-page `sectionIndex` at a heading `depth`. Optional `color`, `opacity`, `fontSize`, and `position` (`center`, `top-left`, `top-right`, `bottom-left`, `bottom-right`).
    </ParamField>
  </Expandable>
</ParamField>

<Tip>
  Furniture is drawn within the page margins. If a header or footer is clipped, increase `page.margin.top` or `page.margin.bottom` (margins are in points — see [Document Options](/configuration/document-options)).
</Tip>

## Example: Company Header and Page-Numbered Footer

The following request renders a policy document with a header in the top-left corner of every page and a centered "Page X of Y" footer in the bottom-right.

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.blinkpdf.io/v1/render \
    --request POST \
    --header 'Accept: application/pdf' \
    --header 'Content-Type: application/json' \
    --header 'x-api-key: bp_xxxxxxxxxxxxxxxxxxxx' \
    --data '{
      "markdown": "# Employee Leave Policy\n\n## Overview\n\nThis policy governs all forms of leave available to full-time employees.\n\n## Annual Leave\n\nAll employees accrue 20 days of annual leave per calendar year.\n\n## Sick Leave\n\nUp to 10 days of paid sick leave are available per year without a medical certificate.",
      "metadata": {
        "title": "Employee Leave Policy",
        "author": "Acme HR Department"
      },
      "page": {
        "margin": { "top": 84, "right": 57, "bottom": 84, "left": 57 }
      },
      "furniture": {
        "slots": {
          "topLeft": {
            "content": [{ "kind": "text", "value": "Acme Corp — Internal Use Only" }]
          },
          "bottomRight": {
            "content": [
              { "kind": "text", "value": "Page " },
              { "kind": "pageNumber" },
              { "kind": "text", "value": " of " },
              { "kind": "totalPages" }
            ]
          }
        }
      }
    }'
  ```

  ```javascript Node.js theme={null}
  const response = await fetch("https://api.blinkpdf.io/v1/render", {
    method: "POST",
    headers: {
      "x-api-key": "bp_xxxxxxxxxxxxxxxxxxxx",
      "Accept": "application/pdf",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      markdown: `# Employee Leave Policy

  ## Overview

  This policy governs all forms of leave available to full-time employees.

  ## Annual Leave

  All employees accrue 20 days of annual leave per calendar year.

  ## Sick Leave

  Up to 10 days of paid sick leave are available per year without a medical certificate.`,
      metadata: {
        title: "Employee Leave Policy",
        author: "Acme HR Department",
      },
      page: {
        margin: { top: 84, right: 57, bottom: 84, left: 57 },
      },
      furniture: {
        slots: {
          topLeft: {
            content: [{ kind: "text", value: "Acme Corp — Internal Use Only" }],
          },
          bottomRight: {
            content: [
              { kind: "text", value: "Page " },
              { kind: "pageNumber" },
              { kind: "text", value: " of " },
              { kind: "totalPages" },
            ],
          },
        },
      },
    }),
  });

  const pdf = await response.arrayBuffer();
  ```

  ```python Python theme={null}
  import httpx

  response = httpx.post(
      "https://api.blinkpdf.io/v1/render",
      headers={
          "x-api-key": "bp_xxxxxxxxxxxxxxxxxxxx",
          "Accept": "application/pdf",
          "Content-Type": "application/json",
      },
      json={
          "markdown": (
              "# Employee Leave Policy\n\n"
              "## Overview\n\n"
              "This policy governs all forms of leave available to full-time employees.\n\n"
              "## Annual Leave\n\n"
              "All employees accrue 20 days of annual leave per calendar year.\n\n"
              "## Sick Leave\n\n"
              "Up to 10 days of paid sick leave are available per year without a medical certificate."
          ),
          "metadata": {
              "title": "Employee Leave Policy",
              "author": "Acme HR Department",
          },
          "page": {
              "margin": {"top": 84, "right": 57, "bottom": 84, "left": 57},
          },
          "furniture": {
              "slots": {
                  "topLeft": {
                      "content": [{"kind": "text", "value": "Acme Corp — Internal Use Only"}],
                  },
                  "bottomRight": {
                      "content": [
                          {"kind": "text", "value": "Page "},
                          {"kind": "pageNumber"},
                          {"kind": "text", "value": " of "},
                          {"kind": "totalPages"},
                      ],
                  },
              },
          },
      },
  )

  with open("leave-policy.pdf", "wb") as f:
      f.write(response.content)
  ```
</CodeGroup>

<Info>
  Furniture is stamped on **every** page by default, including the first and last. To keep a cover page clean, set `"omitFirstPage": true` — this suppresses slots, `decorations`, and the decorative watermark on the first page only. To keep a closing page clean (for example a signature sheet), set `"omitLastPage": true` when the document has more than one page. Use `firstPage` or `lastPage` when those pages need *different* furniture, not a blank page.
</Info>
