Public API reference

Build against HTMLPress without opening the repository.

This page mirrors the repository reference for the authenticated PDF and image APIs. Start with a verified account, create a bearer token in the dashboard, and send requests only to final HTTP 200 targets.

Flow
  1. 1. Register and verify your email address to start the 3-day API trial.
  2. 2. Create an API token in the dashboard. The plaintext token is shown exactly once.
  3. 3. Send Authorization: Bearer htmlpress_… on every GET or POST request to /api/pdf and /api/image.
  4. 4. Revoke tokens from the dashboard at any time if one is exposed or no longer needed.
Getting started

Go from signup to your first API call.

Register, verify your email, log in to the dashboard, create a token, and use that token for every API request. The trial clock starts at verification time, not at registration time.

HTMLPress follows redirects, but conversion succeeds only when the final response is HTTP 200. Private, local, and internal targets are blocked unless you explicitly disable the SSRF guard in a self-hosted environment.

The curl examples below are runnable as-is against https://htmlpress.tech once you substitute your own bearer token.

Authentication

Every public conversion request is bearer-authenticated.

Send Authorization: Bearer htmlpress_... on every GET and POST request to /api/pdf and /api/image.

401 UNAUTHORIZED means the header is missing, malformed, unknown, or revoked. 403 EMAIL_NOT_VERIFIED means the account has not verified its email yet. 403 TRIAL_EXPIRED means the verified account used up its 3-day trial.

Tokens are shown only once when created. Store them immediately in your own secret manager, and revoke them from the dashboard if they are ever exposed.

Authorization: Bearer htmlpress_your-token-here
POST /api/pdf

Render a public webpage into a PDF.

POST JSON is the primary contract. GET remains supported with the same option names as query parameters for backwards compatibility.

Successful responses stream PDF bytes with Content-Type: application/pdf and Content-Disposition: inline; filename="<filename>".

NameTypeDefaultAllowed valuesNotes
urlstringrequiredValid http:// or https:// URLMissing or invalid URLs return 400 INVALID_URL.
waitUntilstringnetworkidle2load, domcontentloaded, networkidle0, networkidle2Shared with the image endpoint.
timeoutinteger ms300001000 to 60000Shared with the image endpoint.
delayinteger ms00 to 10000Extra wait after a successful page load.
filenamestringpage.pdfSanitized filename tokenUsed in Content-Disposition. Quotes, separators, and control chars are stripped.
ignoreHttpsErrorsbooleanfalsetrue, false, 1, 0Only bypasses certificate validation. It does not bypass the SSRF guard.
formatstringA4A0, A1, A2, A3, A4, A5, A6, Letter, Legal, Tabloid, LedgerCase-insensitive. Ignored when width or height is provided.
widthstring or numberunsetCSS length using mm, cm, in, or pxBare numbers are treated as millimeters and override format when set.
heightstring or numberunsetCSS length using mm, cm, in, or pxBare numbers are treated as millimeters and override format when set.
landscapebooleanfalsetrue, false, 1, 0Preferred over the legacy orientation alias.
marginstring or numberunsetCSS length using mm, cm, in, or pxApplies to all sides unless overridden.
marginTopstring or numberunsetCSS length using mm, cm, in, or pxOverrides margin for the top side.
marginRightstring or numberunsetCSS length using mm, cm, in, or pxOverrides margin for the right side.
marginBottomstring or numberunsetCSS length using mm, cm, in, or pxOverrides margin for the bottom side.
marginLeftstring or numberunsetCSS length using mm, cm, in, or pxOverrides margin for the left side.
scalenumber10.1 to 2Matches Puppeteer’s supported range.
pageRangesstringunsetExamples: 1, 1-3, 1-3, 5, 7-9Invalid patterns return 400 INVALID_OPTION.
printBackgroundbooleantruetrue, false, 1, 0Preserves background colors and images.
preferCSSPageSizebooleanfalsetrue, false, 1, 0Passes through to Puppeteer.
omitBackgroundbooleanfalsetrue, false, 1, 0Passes through to Puppeteer.
displayHeaderFooterbooleanfalsetrue, false, 1, 0Enables headerTemplate and footerTemplate.
headerTemplatestringunsetMaximum 10240 bytesHTML string used only when displayHeaderFooter=true.
footerTemplatestringunsetMaximum 10240 bytesHTML string used only when displayHeaderFooter=true.

Runnable curl example

curl -X POST https://htmlpress.tech/api/pdf \
  -H "Authorization: Bearer htmlpress_your-token-here" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com","format":"A5","landscape":true,"margin":10}' \
  -o page.pdf
POST /api/image

Capture a public webpage as PNG, JPEG, or WebP.

POST JSON is the primary contract. GET remains supported with the same option names as query parameters for backwards compatibility.

Binary responses use image/png, image/jpeg, or image/webp. When encoding=base64, the endpoint returns a plain-text base64 string instead.

NameTypeDefaultAllowed valuesNotes
urlstringrequiredValid http:// or https:// URLMissing or invalid URLs return 400 INVALID_URL.
waitUntilstringnetworkidle2load, domcontentloaded, networkidle0, networkidle2Shared with the PDF endpoint.
timeoutinteger ms300001000 to 60000Shared with the PDF endpoint.
delayinteger ms00 to 10000Extra wait after a successful page load.
filenamestringscreenshot.png, screenshot.jpg, or screenshot.webpSanitized filename tokenDefault follows the selected output format.
ignoreHttpsErrorsbooleanfalsetrue, false, 1, 0Only bypasses certificate validation. It does not bypass the SSRF guard.
formatstringpngpng, jpeg, webpPreferred over the legacy type alias.
qualityintegerunset0 to 100Only valid with jpeg or webp.
widthinteger112216 to 5000Viewport width in CSS pixels.
heightinteger158716 to 5000Viewport height in CSS pixels.
deviceScaleFactornumber11 to 3Multiplies final pixel density.
fullPagebooleanfalsetrue, false, 1, 0Captures the full scroll height.
clipobjectunset{ x, y, width, height }JSON-only nested object form. Mutually exclusive with fullPage.
clipXnumberunsetGreater than or equal to 0GET-compatible clip alias. Send together with clipY, clipWidth, and clipHeight.
clipYnumberunsetGreater than or equal to 0GET-compatible clip alias. Send together with clipX, clipWidth, and clipHeight.
clipWidthnumberunsetGreater than 0GET-compatible clip alias. Send together with clipX, clipY, and clipHeight.
clipHeightnumberunsetGreater than 0GET-compatible clip alias. Send together with clipX, clipY, and clipWidth.
omitBackgroundbooleanfalsetrue, false, 1, 0Passes through to Puppeteer.
encodingstringbinarybinary, base64The older implicit base64 default is gone.

Runnable curl example

curl -X POST https://htmlpress.tech/api/image \
  -H "Authorization: Bearer htmlpress_your-token-here" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com","format":"jpeg","quality":80,"width":1280,"height":800,"fullPage":true}' \
  -o screenshot.jpg
Errors

All failures use one consistent envelope.

The public conversion endpoints always return JSON in a single error envelope. The table below excludes dashboard-only and demo-internal codes such as INVALID_CREDENTIALS and RATE_LIMITED.

{
  "error": {
    "code": "ERROR_CODE",
    "message": "Human-readable English explanation.",
    "details": {
      "optional": "metadata"
    }
  }
}
CodeHTTP statusWhen it happens
INVALID_URL400Missing URL, malformed URL, or unsupported protocol.
INVALID_OPTION400A known option has an invalid type, enum, range, or combination.
TARGET_NOT_ALLOWED400The SSRF guard rejected a private, local, link-local, or internal target.
UNAUTHORIZED401The bearer token is missing, malformed, unknown, or revoked.
EMAIL_NOT_VERIFIED403The bearer token belongs to an account whose email is not verified.
TRIAL_EXPIRED403The bearer token belongs to an account whose 3-day trial has expired.
METHOD_NOT_ALLOWED405The request method is not GET or POST.
SSL_ERROR422The target failed TLS certificate validation.
DNS_ERROR422DNS resolution failed during navigation.
CONNECTION_FAILED422Connection was refused, reset, timed out, or was otherwise unreachable.
TARGET_HTTP_ERROR422The final response after redirects was not HTTP 200.
TIMEOUT504Navigation exceeded the configured timeout.
RENDER_FAILED500Page load succeeded, but PDF or image rendering failed.
INTERNAL_ERROR500An unexpected internal error interrupted the conversion.

400 INVALID_OPTION

{
  "error": {
    "code": "INVALID_OPTION",
    "message": "Invalid value for \"width\". Expected an integer between 16 and 5000.",
    "details": {
      "parameter": "width"
    }
  }
}

401 UNAUTHORIZED

{
  "error": {
    "code": "UNAUTHORIZED",
    "message": "You must be signed in to access this resource."
  }
}

403 TRIAL_EXPIRED

{
  "error": {
    "code": "TRIAL_EXPIRED",
    "message": "Your 3-day HTMLPress trial has expired. Email info@bespokeweb.nl to continue."
  }
}

405 METHOD_NOT_ALLOWED

{
  "error": {
    "code": "METHOD_NOT_ALLOWED",
    "message": "Only GET and POST requests are supported for this endpoint."
  }
}

422 TARGET_HTTP_ERROR

{
  "error": {
    "code": "TARGET_HTTP_ERROR",
    "message": "The target page responded with status 404 (Not Found). Only pages that respond with status 200 can be converted.",
    "details": {
      "targetStatus": 404,
      "url": "https://example.com/nope"
    }
  }
}

500 RENDER_FAILED

{
  "error": {
    "code": "RENDER_FAILED",
    "message": "Failed to render the page as a PDF."
  }
}

504 TIMEOUT

{
  "error": {
    "code": "TIMEOUT",
    "message": "The target page did not finish loading within the 30000 ms timeout."
  }
}