---
title: "Public, keyless, rate-limited HTML to PDF (demo)"
method: POST
path: "/api2/convert/demo"
tags: ["HTML To PDF"]
---

# Public, keyless, rate-limited HTML to PDF (demo)

`POST /api2/convert/demo`

Public demo endpoint — no license key required. Output is capped at 5 pages and
watermarked with the SelectPdf demo brand. Engine is forced to `Chromium`. Sync only
(no async polling).

Per-IP rate limit (default 30/hour), global concurrency cap (default 4 in-flight),
and a daily ceiling (default 50,000) apply. SSRF guard rejects URLs that resolve to
private/internal hosts. Parameter clamps reduce `max_load_time` (15s) and `min_load_time` (5s);
`user_password` and `owner_password` are rejected.

Intended for trying out the API. For production use, sign up at
https://selectpdf.com/pricing/ and call `POST /api2/convert` with a license key.

## Request body

- ConversionParameters — Parameters for HTML→PDF conversion. Most fields are optional and have engine-defined defaults; only `key` and (one of) `url`/`html` are required.
  - `key` string, uuid, required — License key. Required for `/api2/convert`; ignored on `/api2/convert/demo`.
  - `async` boolean — If true, submit asynchronously and return 202 + a Job-Id header. Poll `/api2/asyncjob`.
  - `url` string — Web URL to convert. Required if `html` is empty. Mutually exclusive with `html`.
  - `html` string — Raw HTML string to convert. Required if `url` is empty.
  - `base_url` string — Base URL used to resolve relative paths inside `html`.
  - `pdf_name` string — Filename suggested via `Content-Disposition` (default: `Document.pdf`).
  - `page_size` 'A0' | 'A1' | 'A2' | 'A3' | 'A4' | 'A5' | 'A6' | 'A7' | 'A8' | 'Letter' | 'HalfLetter' | 'Ledger' | 'Legal' — Output page size.
  - `page_orientation` 'Portrait' | 'Landscape'
  - `page_width` integer — Custom page width in points (1 pt = 1/72 in). Overrides `page_size` when both `page_width` and `page_height` are non-zero.
  - `page_height` integer — Custom page height in points.
  - `margin_top` integer — Top margin in points.
  - `margin_right` integer — Right margin in points.
  - `margin_bottom` integer — Bottom margin in points.
  - `margin_left` integer — Left margin in points.
  - `engine` 'WebKit' | 'Restricted' | 'Blink' | 'Chromium' — Rendering engine. `WebKit` (default) — broadest compatibility. `Restricted` — WebKit with limited JS. `Blink` — older Chromium fork. `Chromium` — modern Chromium/CEF (recommended for new integrations, required by the demo endpoint).
  - `protocol` integer — TLS protocol selector for fetching `url`. 0 = default (negotiate).
  - `web_page_width` integer — Browser viewport width in pixels used while rendering.
  - `web_page_height` integer — Viewport height in pixels. 0 = automatic (engine picks based on content).
  - `min_load_time` integer — Minimum time (seconds) the engine waits after page load before producing the PDF (lets late-loading scripts settle).
  - `max_load_time` integer — Hard ceiling (seconds) for page load. On the demo endpoint this is clamped to 15.
  - `use_css_print` boolean — Honor CSS `@media print` rules instead of `@media screen`.
  - `background_color` string — PDF page background color (e.g. `#FFFFFF`).
  - `draw_html_background` boolean — If false, the HTML's own backgrounds are stripped (transparent PDF).
  - `disable_javascript` boolean
  - `disable_internal_links` boolean — Suppress in-document anchor hyperlinks.
  - `disable_external_links` boolean — Suppress hyperlinks pointing outside the document.
  - `render_on_timeout` boolean — If `max_load_time` expires, render whatever loaded instead of failing.
  - `keep_images_together` boolean — Avoid splitting images across page breaks.
  - `scale_images` boolean
  - `single_page_pdf` boolean — Produce a single tall page sized to fit the entire content.
  - `page_breaks_enhanced_algorithm` boolean
  - `doc_title` string — PDF metadata: title.
  - `doc_subject` string
  - `doc_keywords` string
  - `doc_author` string
  - `doc_add_creation_date` boolean
  - `viewer_page_layout` 0 | 1 | 2 | 3 | 4 | 5 — PDF viewer page layout: 0=SinglePage, 1=OneColumn (default), 2=TwoColumnLeft, 3=TwoColumnRight, 4=TwoPageLeft, 5=TwoPageRight.
  - `viewer_page_mode` 0 | 1 | 2 | 3 | 4 | 5 — PDF viewer page mode: 0=UseNone (default), 1=UseOutlines, 2=UseThumbs, 3=FullScreen, 4=UseOC, 5=UseAttachments.
  - `viewer_center_window` boolean
  - `viewer_display_doc_title` boolean
  - `viewer_fit_window` boolean
  - `viewer_hide_menu_bar` boolean
  - `viewer_hide_toolbar` boolean
  - `viewer_hide_window_ui` boolean
  - `show_header` boolean — Render a header band on each page sourced from `header_url` or `header_html`.
  - `header_display_on_first_page` boolean
  - `header_display_on_odd_pages` boolean
  - `header_display_on_even_pages` boolean
  - `header_height` integer — Header band height in points.
  - `header_url` string — URL whose rendered output becomes the page header.
  - `header_html` string — Inline HTML used as the page header (alternative to `header_url`).
  - `header_base_url` string
  - `header_web_page_width` integer
  - `header_web_page_height` integer
  - `show_footer` boolean
  - `footer_display_on_first_page` boolean
  - `footer_display_on_odd_pages` boolean
  - `footer_display_on_even_pages` boolean
  - `footer_display_on_last_page` boolean
  - `footer_height` integer
  - `footer_url` string
  - `footer_html` string
  - `footer_base_url` string
  - `footer_web_page_width` integer
  - `footer_web_page_height` integer
  - `page_numbers` boolean — Render page numbers in the footer band.
  - `page_numbers_first` integer — Page number assigned to the first page (lets you offset numbering).
  - `page_numbers_offset` integer — Number of leading pages to suppress numbering on.
  - `page_numbers_template` string — Template using `{page_number}` and `{total_pages}` placeholders.
  - `page_numbers_font_name` string
  - `page_numbers_font_size` integer
  - `page_numbers_alignment` 1 | 2 | 3 — 1=Left, 2=Center, 3=Right.
  - `page_numbers_color` string — Hex color for the page numbers (e.g. `#000000`).
  - `page_numbers_pos_y` integer — Vertical position of page numbers in points from the bottom.
  - `pdf_bookmarks_selectors` string — Semicolon-separated CSS selectors. Matched elements become PDF bookmarks.
  - `pdf_hide_elements` string — Semicolon-separated CSS selectors. Matched elements are hidden before rendering.
  - `pdf_show_only_element_id` string — Render only the element with this `id` (everything else hidden).
  - `pdf_web_elements_selectors` string — Semicolon-separated CSS selectors whose bounding boxes are reported back via `X-SelectPdf-Web-Elements` (sync) or `/api2/webelements` (async).
  - `user_password` string — Password required to open the PDF. Rejected by the demo endpoint.
  - `owner_password` string — Password required to modify / print the PDF. Rejected by the demo endpoint.
  - `auth_username` string — HTTP Basic-Auth username used when fetching `url`.
  - `auth_password` string
  - `cookies` object — Cookie name → value map sent when fetching `url` (JSON body only).
  - `cookies_string` string — Query-string-encoded cookies (form / GET equivalent of `cookies`).
  - `startup_mode` string — Engine startup mode hint (`automatic`, `manual`).
  - `skip_decoding` boolean — If true, treat the URL as already-decoded (do not re-percent-decode). Internal default for forwarded calls.
  - `raw_parameters` string — Optional JSON blob containing this entire object. When present, the receiver deserializes it and ignores all other form fields. Used by the SDK's remote-worker proxy.
  - `response_content_type` 0 | 1 — 0 = `binary/octet-stream` (default, makes browsers download). 1 = `application/pdf` (browsers may render inline).

## Response `200`

5-page-capped, watermarked PDF returned in the response body.

## Other responses

- `400` — Body is a JSON object describing the rejection. Shapes: - `{ "error":"unsafe_url", "field":"url", "reason":"private_ip" }` (SSRF guard) - `{ "error":"unsupported_in_demo", "field":"user_password", "upgrade":"https://selectpdf.com/pricing/" }` - `{ "error":"missing_input" }` if neither `url` nor `html` were supplied
- `413` — Request body exceeds the demo cap (default 1 MB). Use the production endpoint for larger payloads.
- `429` — Rate limited. Body is `{ "error":"rate_limited", "reason":"per_ip"|"daily_cap", "upgrade":"…" }`. `Retry-After` header carries seconds to wait.
- `499` — Conversion error. Body is plain text.
- `503` — Demo concurrency cap reached. Body is `{ "error":"rate_limited", "reason":"concurrency", "upgrade":"…" }`. `Retry-After` is short (default 5s).

---

[API](https://skmtc.dev/selectpdf/apis/selectpdf-rest-api.md) · [All operations](https://skmtc.dev/selectpdf/apis/selectpdf-rest-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/selectpdf/selectpdf-rest-api/revisions/3e8de86ac045/schema)
