# Generation API — create PDFs, social/OG images, charts, QR codes, barcodes (EAN/UPC/Code-128/ISBN), favicon bundles, WiFi-join QR, code-snippet images, vCard (.vcf) and iCal (.ics) files from templates, inline HTML/CSS, or a single parameter set (stateless: input → ready-to-use asset)

> Render a PDF from inline HTML/CSS (Jinja2) or a built-in template_name + data (invoice/receipt/certificate/report). WeasyPrint, fonts pinned, network-off. Output: inline base64 (≤8MB) or one-time download token.
> ReefAPI engine `generate` · 21 endpoints · clean JSON, no scraping or browsers to manage.

## How to call
- **Endpoint:** `POST https://api.reefapi.com/generate/v1/<action>` with a JSON body.
- **Auth:** header `x-api-key: <YOUR_REEFAPI_KEY>` — create one free (1,000 credits, no card): https://reefapi.com/signup
- **Response (every call):** `{ ok: boolean, data: ..., meta: { record_count, credits, ... }, error: { code, message } }` — branch on `ok`. Failed or blocked calls are free.
- **One key + one shared credit pool** across every ReefAPI API. Per-call credits are listed on each endpoint below.
- **Use it from an AI agent (MCP):** connect `https://api.reefapi.com/mcp` (remote streamable-http, `Authorization: Bearer <key>`) and your assistant can call these actions directly.

## Endpoints

### POST /generate/v1/pdf_render — 4 credits
Render a PDF from inline HTML/CSS (Jinja2) or a built-in template_name + data (invoice/receipt/certificate/report). WeasyPrint, fonts pinned, network-off. Output: inline base64 (≤8MB) or one-time download token.

**Parameters:**
- `html` (string, optional) — Inline HTML/CSS document (Jinja2 syntax allowed; rendered in a SANDBOXED env — no code execution). Mutually exclusive with template_name.
- `template_name` (enum, optional) — Built-in PDF template (stateless — lives in engine, not stored). Supply `data` matching its contract (see template_list). [one of: invoice, receipt, certificate, report]
- `data` (object, optional) — Template variables (JSON object) — merged into the template. For built-ins see each template's data_contract.
- `paper` (enum, optional) — Page size override for built-in templates. [one of: A4, A4 landscape, Letter, Letter landscape, A5, Legal]
- `filename` (string, optional) — Suggested download filename.
- `allow_hosts` (string, optional) — Comma-separated https hosts whose images/CSS the PDF may fetch (default NONE = network-off, SSRF-safe). Use data: URIs to embed assets without this.

**Returns:** file{file_b64|download_token, filename, content_type=application/pdf, bytes, pages_hint, delivery}

**Example request body:**
```json
{
  "template_name": "invoice",
  "data": {
    "company": {
      "name": "Acme"
    },
    "items": [
      {
        "description": "Widget",
        "qty": 2,
        "unit_price": 9.5
      }
    ],
    "subtotal": 19,
    "total": 19
  }
}
```

### POST /generate/v1/pdf_from_html — 4 credits
Shortcut for rendering inline HTML directly to PDF — the same WeasyPrint engine as pdf_render; `html` is required.

**Parameters:**
- `html` (string, required) — HTML/CSS document to render (Jinja2 allowed, sandboxed).
- `data` (object, optional) — Optional Jinja2 variables for the HTML.
- `paper` (enum, optional) — Page size (only if your CSS uses {{ paper }}). [one of: A4, A4 landscape, Letter, A5, Legal]
- `filename` (string, optional) — Suggested filename.
- `allow_hosts` (string, optional) — Allowlisted https hosts for remote assets (default none).

**Returns:** file{...,content_type=application/pdf}

**Example request body:**
```json
{
  "html": "<!doctype html><h1>{{ t }}</h1>",
  "data": {
    "t": "Hello"
  }
}
```

### POST /generate/v1/pdf_from_url — 4 credits
Render a built-in or inline template to PDF, populating it with data fetched live from a JSON URL you supply. Useful when your invoice or report data lives at a public API endpoint — no manual copy-paste needed.

**Parameters:**
- `data_url` (string, required) — https URL returning a JSON object used as template `data`.
- `template_name` (enum, optional) — Built-in template to fill. [one of: invoice, receipt, certificate, report]
- `html` (string, optional) — Inline HTML template (instead of template_name).
- `data_path` (string, optional) — Optional dotted path into the fetched JSON to use as data (e.g. 'result.invoice').
- `paper` (enum, optional) — Page size override. [one of: A4, A4 landscape, Letter, A5, Legal]
- `filename` (string, optional) — Suggested filename.

**Returns:** file{...,content_type=application/pdf}, data_source

### POST /generate/v1/og_image — 2 credits
Render a social / Open Graph card image (1200×630 default) from a built-in template or an inline layout spec. Supports automatic text-wrap and font scaling for long titles, colour gradients and badge overlays.

**Parameters:**
- `template_name` (enum, optional, default "og_basic") — Built-in card layout. See template_list for each layout's vars. [one of: og_basic, og_article, og_quote, og_product]
- `vars` (object, optional) — Card content (JSON): title/subtitle/badge/quote/author/site/name/tagline/cta + colors bg/bg2/fg/accent (hex).
- `layout` (object, optional) — Inline layout override (JSON) — {size:[w,h], ...} for a fully custom card without a built-in template.
- `width` (integer, optional, default 1200) — Canvas width px.
- `height` (integer, optional, default 630) — Canvas height px.
- `format` (enum, optional, default "png") — Output image format. [one of: png, jpeg, webp]
- `filename` (string, optional) — Suggested filename.

**Returns:** file{file_b64|download_token, content_type=image/png|jpeg|webp, bytes}

**Example request body:**
```json
{
  "template_name": "og_basic",
  "vars": {
    "title": "Launch day",
    "subtitle": "v1.0 is live"
  }
}
```

### POST /generate/v1/image_from_template — 2 credits
Alias of og_image (explicit Bannerbear 'create image from template' naming). template_name + vars → PNG.

**Parameters:**
- `template_name` (enum, required) — Built-in image template. [one of: og_basic, og_article, og_quote, og_product]
- `vars` (object, optional) — Template variables (see template_list).
- `width` (integer, optional, default 1200) — Canvas width px.
- `height` (integer, optional, default 630) — Canvas height px.
- `format` (enum, optional, default "png") — Output format. [one of: png, jpeg, webp]
- `filename` (string, optional) — Suggested filename.

**Returns:** file{...,content_type=image/*}

**Example request body:**
```json
{
  "template_name": "invoice"
}
```

### POST /generate/v1/image_from_url — 2 credits
Render an image template with `vars` fetched from a JSON URL (proxy, SSRF-validated). Data-driven banner generation.

**Parameters:**
- `data_url` (string, required) — https URL returning a JSON object used as card `vars`.
- `template_name` (enum, optional, default "og_basic") — Built-in template. [one of: og_basic, og_article, og_quote, og_product]
- `layout` (object, optional) — Inline layout override (JSON).
- `data_path` (string, optional) — Dotted path into the JSON to use as vars.
- `width` (integer, optional, default 1200) — Canvas width px.
- `height` (integer, optional, default 630) — Canvas height px.
- `format` (enum, optional, default "png") — Output format. [one of: png, jpeg, webp]
- `filename` (string, optional) — Suggested filename.

**Returns:** file{...,content_type=image/*}, data_source

### POST /generate/v1/chart — 1 credit
Render a chart from a Chart.js-style spec — returns a PNG or SVG image. Supported chart types: bar, horizontal_bar, line, area, pie, doughnut, scatter and radar. Powered by a matplotlib backend.

**Parameters:**
- `spec` (object, required) — Chart spec: {type, data:{labels:[...], datasets:[{label, data:[...], color?}]}, options:{title, x_label, y_label, width, height, legend}}.
- `format` (enum, optional, default "png") — Output format. [one of: png, svg]
- `filename` (string, optional) — Suggested filename.

**Returns:** file{file_b64|download_token, content_type=image/png|svg+xml, bytes, chart_type}

**Example request body:**
```json
{
  "spec": {
    "type": "bar",
    "data": {
      "labels": [
        "A",
        "B",
        "C"
      ],
      "datasets": [
        {
          "label": "x",
          "data": [
            1,
            2,
            3
          ]
        }
      ]
    }
  }
}
```

### POST /generate/v1/chart_types — 0 credits
List all supported chart types with a description of each. No input required.

**Parameters:** none

**Returns:** types[{type, description}]

### POST /generate/v1/batch_pdf — 4 credits
Render up to 20 PDFs in one call. `jobs` = array of pdf_render param objects.

**Parameters:**
- `jobs` (object, required) — Array of ≤20 pdf_render param objects ({html|template_name, data, ...}).

**Returns:** files[] (one delivery entry per job; per-job error captured inline), count

### POST /generate/v1/batch_image — 2 credits
Render up to 20 images in one call. `jobs` = array of og_image param objects.

**Parameters:**
- `jobs` (object, required) — Array of ≤20 og_image param objects ({template_name|layout, vars, ...}).

**Returns:** files[] (one entry per job), count

### POST /generate/v1/template_list — 0 credits
List built-in templates (PDF + image) with their data contracts. Stateless — there is NO stored-template management (create/upload/delete out of scope).

**Parameters:** none

**Returns:** pdf[{name,description,data_contract}], og_image[{name,...,size}], note

### POST /generate/v1/validate_html — 0 credits
Lint HTML/CSS for the PDF path WITHOUT rendering: flags remote resources that the SSRF-safe renderer will block, size, and tag-balance hints. Deterministic.

**Parameters:**
- `html` (string, required) — HTML document to lint.

**Returns:** valid, bytes, remote_resources[], tags_open, tags_close, issues[]

**Example request body:**
```json
{
  "html": "<img src='https://evil.example/x.png'>"
}
```

### POST /generate/v1/health — 0 credits
Renderer diagnostics — which backends (WeasyPrint/Pillow/matplotlib) are loadable and their versions. No input.

**Parameters:** none

**Returns:** pdf_backend, weasyprint_version, image_backend, chart_backend, matplotlib_version, max_image_pixels

### POST /generate/v1/qr — 1 credit
Generate a QR code (PNG or SVG) with custom fg/bg color, error-correction, and an OPTIONAL center logo fetched from logo_url (SSRF-guarded, via proxy). Use error_correction=h when embedding a logo so it stays scannable.

**Parameters:**
- `data` (string, required) — The content to encode: a URL, text, vCard string, etc.
- `format` (enum, optional, default "png") — Output image format. png supports logo-embed + colors; svg is scalable (logo-embed requires png). [one of: png, svg]
- `error_correction` (enum, optional, default "m") — Recovery level: l~7% · m~15% · q~25% · h~30%. Use h with a logo. [one of: l, m, q, h]
- `scale` (integer, optional, default 8) — Module size in pixels.
- `border` (integer, optional, default 4) — Quiet-zone width in modules (spec default 4).
- `color` (string, optional) — Foreground (dark) color: #rrggbb / #rgb / basic CSS name.
- `background` (string, optional) — Background color, or 'transparent'.
- `logo_url` (string, optional) — URL of a logo to embed in the center (PNG output only). Fetched through the proxy with a full SSRF guard.
- `logo_size` (number, optional, default 0.22) — Logo size as a fraction of the QR side (0.05–0.30; >0.25 risks unscannable codes even at EC-H).

**Returns:** png_base64+data_uri | svg, version, error_correction, designator, modules, is_micro, logo_embedded

**Example request body:**
```json
{
  "data": "https://reefapi.com",
  "format": "png"
}
```

### POST /generate/v1/barcode — 1 credit
Generate a 1D barcode IMAGE (PNG or SVG) from data: EAN-13/8, UPC-A, Code-128, Code-39, ISBN-10/13, ITF, GS1-128, JAN, PZN, Codabar. Check digits are validated — a wrong EAN/UPC/ISBN check digit returns a structured error, not a silent fix.

**Parameters:**
- `data` (string, required) — The value to encode. For EAN/UPC supply the digits; the check digit is computed (or validated if you include it).
- `type` (enum, required) — Barcode symbology. [one of: ean13, ean8, ean14, upca, code128, code39, isbn13, isbn10, issn, itf, gs1_128, jan, pzn, codabar]
- `format` (enum, optional, default "png") — Output image format. [one of: png, svg]
- `show_text` (boolean, optional, default true) — Print the human-readable value under the bars.
- `module_height` (number, optional, default 15) — Bar height in mm.
- `color` (string, optional) — Bar color (#rrggbb / name).
- `background` (string, optional) — Background color (#rrggbb / name).

**Returns:** png_base64+data_uri | svg, type, full_code (with check digit), label, bytes; on bad check digit → error with the valid_code

**Example request body:**
```json
{
  "data": "5901234123457",
  "type": "ean13"
}
```

### POST /generate/v1/code_image — 2 credits
Render a syntax-highlighted code snippet as a PNG with a carbon/ray.so-style window frame. 500+ languages (Pygments), 40+ themes, optional line numbers.

**Parameters:**
- `code` (string, required) — The source code to render.
- `language` (string, optional) — Language for highlighting (python, javascript, go, rust, sql…). Omit to auto-detect.
- `theme` (enum, optional, default "monokai") — Color theme (Pygments style). [one of: abap, algol, algol_nu, arduino, autumn, borland, bw, coffee, colorful, default, dracula, emacs, friendly, friendly_grayscale, fruity, github-dark, gruvbox-dark, gruvbox-light, igor, inkpot, lightbulb, lilypond, lovelace, manni, material, monokai, murphy, native, nord, nord-darker, one-dark, paraiso-dark, paraiso-light, pastie, perldoc, rainbow_dash, rrt, sas, solarized-dark, solarized-light, staroffice, stata-dark, stata-light, tango, trac, vim, vs, xcode, zenburn]
- `window_style` (enum, optional, default "dark") — Frame: dark/darker/light window chrome with traffic-light dots, or 'none' for a bare image. [one of: dark, darker, light, none]
- `line_numbers` (boolean, optional, default false) — Show line numbers in the gutter.
- `font_size` (integer, optional, default 20) — Font size in px.

**Returns:** png_base64+data_uri, language (resolved), theme, window_style, lines, bytes

**Example request body:**
```json
{
  "code": "print('hello')",
  "language": "python"
}
```

### POST /generate/v1/favicon — 2 credits
Turn one source image into a complete favicon bundle: multi-resolution favicon.ico, a named PNG set (16→512 incl. apple-touch-icon + android-chrome), site.webmanifest, and the ready-to-paste <head> <link> snippet. Source from image_url (SSRF-guarded) or a base64 upload.

**Parameters:**
- `image_url` (string, optional) — URL of the source image (PNG/JPG/etc). Fetched through the proxy with a full SSRF guard. Provide this OR image_base64.
- `image_base64` (string, optional) — Base64-encoded source image (data-URI prefix accepted). Use instead of image_url for direct uploads.

**Returns:** favicon_ico{png_base64,sizes}, pngs{name:{size,png_base64}}, site_webmanifest{}, link_snippet (HTML), source{width,height}

### POST /generate/v1/vcard — 1 credit
Build a vCard (.vcf) contact file from contact fields (vCard 3.0 or 4.0). Returns the raw .vcf text + a base64 data-URI you can download or encode into a QR.

**Parameters:**
- `full_name` (string, optional) — Full display name (or supply first_name/last_name).
- `first_name` (string, optional) — Given name.
- `last_name` (string, optional) — Family name.
- `organization` (string, optional) — Company/organization.
- `title` (string, optional) — Job title.
- `phone` (string, optional) — Phone number(s) — string or array.
- `email` (string, optional) — Email address(es) — string or array.
- `url` (string, optional) — Website URL(s) — string or array.
- `address` (string, optional) — Postal address (single line).
- `note` (string, optional) — Free-text note.
- `birthday` (string, optional) — Birthday (YYYY-MM-DD).
- `version` (enum, optional, default "3.0") — vCard spec version (3.0 = widest compatibility, 4.0 = modern). [one of: 3.0, 4.0]
- `as_qr` (boolean, optional, default false) — Also return a scannable PNG QR of the vCard (add-to-contacts).

**Returns:** vcard (raw .vcf text), data_uri (text/vcard), full_name, version, field_count [+ qr_png_base64 if as_qr]

**Example request body:**
```json
{
  "full_name": "Jane Doe",
  "email": "jane@acme.com",
  "phone": "+15550100"
}
```

### POST /generate/v1/ical — 1 credit
Build an iCalendar (.ics) event file from event fields (RFC 5545). Supports timed or all-day events, end-time or duration, location, description, organizer. Returns the raw .ics + a base64 data-URI.

**Parameters:**
- `summary` (string, required) — Event title.
- `start` (string, required) — Start: ISO-8601 (2026-07-01T15:00:00+00:00) or YYYY-MM-DD (all-day).
- `end` (string, optional) — End time (ISO-8601 or YYYY-MM-DD). Omit to use duration_minutes.
- `duration_minutes` (integer, optional, default 0) — Event length in minutes (used when `end` is absent).
- `location` (string, optional) — Event location.
- `description` (string, optional) — Event details.
- `url` (string, optional) — Event URL.
- `organizer_email` (string, optional) — Organizer email.
- `uid` (string, optional) — Stable UID (auto-generated if omitted).
- `as_qr` (boolean, optional, default false) — Also return a scannable PNG QR of the event.

**Returns:** ical (raw .ics text), data_uri (text/calendar), summary, all_day, uid, start [+ qr_png_base64 if as_qr]

**Example request body:**
```json
{
  "summary": "Standup",
  "start": "2026-07-01T15:00:00Z",
  "duration_minutes": 30
}
```

### POST /generate/v1/wifi — 1 credit
Generate a WiFi-join QR code (PNG/SVG) from network credentials — scan to connect, no typing. Encodes the standard WIFI: payload (WPA/WEP/open, hidden networks).

**Parameters:**
- `ssid` (string, required) — Network name (SSID).
- `password` (string, optional) — Network password (required unless encryption=nopass).
- `encryption` (enum, optional, default "WPA") — Security type: WPA (incl. WPA2/WPA3), WEP, or nopass (open network). [one of: WPA, WEP, nopass]
- `hidden` (boolean, optional, default false) — Mark the network as hidden (non-broadcast SSID).
- `format` (enum, optional, default "png") — Output image format. [one of: png, svg]
- `scale` (integer, optional, default 8) — Module size in pixels.
- `error_correction` (enum, optional, default "m") — QR recovery level. [one of: l, m, q, h]

**Returns:** png_base64+data_uri | svg, ssid, encryption, hidden, version, modules

**Example request body:**
```json
{
  "ssid": "MyNet",
  "password": "pw12345",
  "encryption": "WPA"
}
```

### POST /generate/v1/batch — 1 credit
Generate up to 50 small assets in one request. Items run independently — a bad item yields its own error entry, never fails the batch. NOTE: items that fetch a remote logo_url/image_url ARE supported and SSRF-guarded.

**Parameters:**
- `items` (array, required) — Up to 50 items, each {action, params} where action is qr|barcode|code_image|favicon|vcard|ical|wifi.

**Returns:** count, ok_count, results[{action, ok, data|error}]

**Example request body:**
```json
{
  "items": [
    {
      "action": "qr",
      "params": {
        "data": "x"
      }
    },
    {
      "action": "barcode",
      "params": {
        "data": "5901234123457",
        "type": "ean13"
      }
    },
    {
      "action": "barcode",
      "params": {
        "data": "bad",
        "type": "ean13"
      }
    }
  ]
}
```

## More
- Try it live, no code: https://reefapi.com/playground?engine=generate
- Human docs page: https://reefapi.com/docs/generate
- Every ReefAPI API in one file (for your AI): https://reefapi.com/llms-full.txt
