---
title: "Render Pdf"
method: POST
path: "/api/v1/render/pdf"
tags: ["Casa Daily — Render"]
---

# Render Pdf

`POST /api/v1/render/pdf`

## Request

- Base URL: `https://api.casaintelligence.com.au` (the document declares no server; this is the origin it was published from)
- URL: `https://api.casaintelligence.com.au/api/v1/render/pdf`
- Auth: API key in header `X-API-Key`

Render HTML+CSS to a PDF byte stream.

Auth: X-API-Key (server-to-server, never browser-facing).

Response: `application/pdf` stream. Body starts with `%PDF-` magic
bytes (asserted in tests). Caller pipes the response straight into
Supabase Storage; the endpoint itself is stateless.

Failure modes:
  - 413 Payload Too Large — body exceeded MAX_BODY_BYTES.
  - 422 Unprocessable Entity — Pydantic validation (e.g. empty
    html, unknown page_size).
  - 504 Gateway Timeout — WeasyPrint took longer than
    RENDER_TIMEOUT_SECONDS.
  - 500 Internal Server Error — WeasyPrint raised (malformed
    HTML, unparseable CSS, missing font, etc.). Message includes
    the exception class so the caller can show a diagnostic.

Body-size guard runs as a Header-only dependency (see
`_enforce_body_size`) so we 413 before parsing a 50MB envelope.

## Headers

- `content-length` string, nullable

## Request body

- RenderPdfRequest: The HTML+CSS payload Casa Daily POSTs to us. `html` is the FULL document — DOCTYPE, `<html>`, `<head>`, `<style>`/`<link>`, `<body>`. WeasyPrint parses it as-is. `base_css` is an optional extra stylesheet appended to the document. We support it as a separate field so Casa Daily can keep its print-grade brand CSS in one file and reuse it across both report templates — it doesn't have to inline it into every HTML string. If present, it's added as a WeasyPrint `CSS(string=...)` stylesheet alongside the document's own embedded styles. `page_size` / `orientation` drive the `@page` rule we prepend so the caller doesn't have to re-state it in every template. The caller's own CSS can still override these via its own `@page` rule (last one wins per CSS cascade).
  - `html` string, required: Full HTML document — DOCTYPE through </html>.
  - `base_css` string, nullable: Optional extra stylesheet, appended to the document.
  - `page_size` 'A4' | 'Letter': WeasyPrint page size — A4 or Letter.
  - `orientation` 'portrait' | 'landscape': Page orientation — portrait or landscape.

## Response `200`

Successful Response

- unknown

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/casaintelligence/apis/casa-intelligence-engine.md) · [All operations](https://skmtc.dev/casaintelligence/apis/casa-intelligence-engine/llms.txt) · [OpenAPI document](https://skmtc.dev/casaintelligence/apis/casa-intelligence-engine/revisions/71d711039de0?raw)
