HTTP reference · 6 min read

REST API

The Laravel package is the recommended way to use BladePDF, but the underlying HTTP API is a single multipart endpoint you can call from any language. This page documents that raw contract.

Using Laravel?

Skip this page and use the BladePDF facade — it builds these requests, uploads assets, and handles responses for you.

Endpoint

Render endpoint
bash
 1POST https://api.bladepdf.com/render

The request body is multipart/form-data. By default, a successful response streams the generated PDF back as application/pdf. Send Prefer: respond-async to receive an acceptance response instead.

Authentication

Send your API key as a bearer token. Requests without a valid key are rejected with 401.

Authorization header
bash
 1Authorization: Bearer blpdf_xxxxxxxxxxxxxxxxxxxxxxxx

Form fields

All fields are optional except source. JSON fields are sent as a string value; HTML, context, and assets are sent as file parts.

Field Kind Description
sourceJSONRender source. {"type":"html"} or {"type":"template","templateId":"…"}.
htmlFileThe document HTML. Required when source.type is html.
header_htmlFileRepeating page header HTML (HTML renders only).
footer_htmlFileRepeating page footer HTML (HTML renders only).
contextFileJSON context for the template. Required when source.type is template.
asset:///<name>FileAn uploaded asset, referenced from your HTML/CSS as asset:///<name>. Repeat for each asset.
pdf_optionsJSONPDF options such as format, margins, orientation, scale, page ranges. See Options.
wait_untilTextWait condition: load, domcontentloaded, networkidle0, networkidle2, or function.
wait_functionTextA JavaScript expression to wait for before capturing (paid plans).
emulate_mediaTextMedia type to emulate: screen or print.
metadataJSONYour own key/value metadata, echoed back on webhooks and render history.
store_pdfTextSet to persist the output as a stored PDF. Required with Prefer: respond-async.
webhookJSONPer-request callback for an async render: {"url":"…","secret":"…","events":["pdf.rendered"]}. See Webhooks.

Example: render raw HTML

curl
bash
 1curl https://api.bladepdf.com/render \
 2  -H "Authorization: Bearer $BLADEPDF_API_KEY" \
 3  -F 'source={"type":"html"};type=application/json' \
 4  -F 'html=@invoice.html;type=text/html' \
 5  -F 'pdf_options={"format":"A4","printBackground":true};type=application/json' \
 6  -o invoice.pdf

Example: render a cloud template

curl
bash
 1curl https://api.bladepdf.com/render \
 2  -H "Authorization: Bearer $BLADEPDF_API_KEY" \
 3  -F 'source={"type":"template","templateId":"invoice.standard"};type=application/json' \
 4  -F 'context=@context.json;type=application/json' \
 5  -F 'store_pdf=1' \
 6  -o invoice.pdf

Response

Synchronously generated PDF

A successful render returns 200 OK and streams the PDF as the response body with Content-Type: application/pdf. Every response includes an x-request-id header — log it so you can correlate a request with its entry in render history and any webhook you receive.

When store_pdf=1 succeeds on a synchronous request, the response also includes a Link header with rel="stored-pdf". Laravel clients expose that value as $result->storedPdfUrl().

Stored PDF link header
http
 1Link: <https://app.bladepdf.com/pdf/{workspace_id}/{request_id}.pdf?expires=...&signature=...>; rel="stored-pdf"; type="application/pdf"

Asynchronous acceptance

Add Prefer: respond-async, Accept: application/json, and store_pdf=1. After the request body has been parsed, validated, checked for storage, and accepted within your workspace capacity, the API returns 202 Accepted. If all concurrency slots are busy, the request may wait before this response. Rendering continues in the background after the HTTP response.

Async template render
bash
 1curl https://api.bladepdf.com/render \
 2  -H "Authorization: Bearer $BLADEPDF_API_KEY" \
 3  -H 'Prefer: respond-async' \
 4  -H 'Accept: application/json' \
 5  -F 'source={"type":"template","templateId":"invoice.standard"};type=application/json' \
 6  -F 'context=@context.json;type=application/json' \
 7  -F 'metadata={"reference":"INV-2026-0042"};type=application/json' \
 8  -F 'store_pdf=1' \
 9  -F 'webhook={"url":"https://example.com/bladepdf/webhook","secret":"whsec_request_secret","events":["pdf.rendered","pdf.failed"]};type=application/json'
202 Accepted
json
 1{
 2  "request_id": "req_abc123",
 3  "reference": "INV-2026-0042"
 4}

Omitting store_pdf=1 returns 400. If the workspace cannot store another PDF because its storage quota is full, the async request returns 403 before it is accepted.

Status codes

Status Meaning
200PDF generated and returned in the body.
202Async render accepted for background processing.
400Invalid request — malformed fields, bad source, or invalid options.
401Missing or invalid API key.
403Plan limit reached — monthly generations, bandwidth, or storage.
413Request payload exceeds your plan's maximum.
429No render capacity — the queue is full. Retry with backoff.
5xxRender failure or an unexpected server error.

See Limits & Concurrency for what drives these responses and Errors for handling them.

Was this page helpful?
Let us know if something's missing or unclear.