API reference
Every endpoint with its parameters, body and responses, from the OpenAPI description.
Every request carries Authorization: Bearer rpdf_… unless an endpoint says it is public; every response carries Request-Id and the account's RateLimit-* headers (Pricing and limits).
POST /v1/pdf#
HTML to PDF
Prints a whole HTML document. With data, the HTML is a template ({{ … }}, {% for %}, {% if %}) filled first.
Parameters
Idempotency-Keyheader · string- A key of yours (a UUID) that makes the request safe to repeat: within 24 hours the same key and body get the first result back, with nothing printed or charged twice. Another body under the same key is
422 idempotency_key_reused. Acceptheader ·"application/pdf"|"application/json"application/pdf(the default): the PDF itself.application/json: the PDF's link and facts (Pdf), the file kept 24 hours.
Body
htmlstring- The whole HTML document, with its <style>. Images and fonts by https URL or data: URI. Up to 15 MB.
urlstring- Instead of
html: the page's public http(s) address (ports 80/443). It is fetched anonymously (redirects followed, each checked; 20 s, 15 MB) and printed from where it was found (its relative addresses resolve there). dataobject- When given,
htmlis a template filled with these values first. filenamestring- The PDF's file name (else the document's <title>).
optionsOptionsenginestring- Pin the print to an engine version (
GET /v1/engines): the current one, or a previous one, kept printing until three newer engines have shipped and 30 days at most. Without it, the current engine.
Needs a key with the print scope (scopes).
Responses
- 200
- The PDF.
X-Page-CountPages printed (and counted to the plan).Content-DispositionThe file's name:filename, else the document's<title>.X-ReflowPDF-Markfree-allowance-usedwhen a Free account's pages without the mark are used up for the month.ReflowPDF-Missing-VariablesThe template's variables the data did not give (comma-separated, URL-encoded); printed empty.ReflowPDF-Missing-GlyphsThe characters no font had a glyph for (UTF-8, percent-encoded): printed as empty boxes; add a font that covers them.ReflowPDF-Missing-FontsThe font families the document named that no face answered (each percent-encoded, comma-separated): their text took the next family of its list.ReflowPDF-Skipped-ResourcesThe addresses the print went without (space-separated; as many as 2 KB holds, then+Nfor the rest; the JSON response lists them all).Idempotent-Replayedtruewhen this is the answer of an earlier request with the same Idempotency-Key.ReflowPDF-EngineThe engine version that printed it (GET /v1/engines).ReflowPDF-ScriptsWithoptions.javascript: what the document's scripts did: thescriptsobject of the JSON response, as percent-encoded JSON (run,errors,error_count,skipped,modules,stopped,console).
- 201
- With
Accept: application/json: the PDF's link and facts. - 400
- The request is not valid: the problem names the field (
invalid_request); or a template that does not read: an expression, a tag or a filter it cannot parse (template_error). - 401
- No API key, or one not valid.
- 403
- A claim of the Pro and Max plans (PDF/A, PDF/X, PDF/UA-2) on another plan (
plan_required); a key without the scope the route asks for (insufficient_scope), or used from an address it is not kept to (ip_not_allowed). - 410
- The answer of an Idempotency-Key is no longer kept: a PDF or images an hour, a link 24 hours (
file_expired). - 413
- The body is over 15 MB, the document over the print's size, or a result over the 1 GB a file stored for a link may be (
result_too_large). - 415
- The body is not JSON.
- 422
- Not possible for this document (a claim it cannot keep, a page it does not have), a PDF that cannot be read (
invalid_pdf) or is encrypted without its password (pdf_encrypted), the layout did not settle, the Idempotency-Key was used with another request, or the page ofurlcould not be fetched (document_unreachable: not public, not HTML, over 15 MB or 20 s, or it answered an error), or theenginenamed prints here no more (engine_unavailable). - 429
- Too many requests of this account at once, or in the last minutes, or jobs not finished (
rate_limited); or the files it stores for links fill its plan's space: Free 256 MB, Pro and Max 2 GB (storage_quota). - 500
- Our error (
internal_error): give therequest_idto support. - 502
- The engine failed on our side (
render_failed): tried again, it may print. - 503
- The engine is busy (
engine_busy), the print took over its time limit (90 s for a request, 3 minutes for a job:render_timeout), or files cannot be stored for links right now (storage_full). SeeRetry-After.
curl -X POST https://api.reflowpdf.com/v1/pdf \
-H "Authorization: Bearer $REFLOWPDF_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d @- <<'JSON'
{
"html": "<!doctype html><html><head><title>Hello</title><style>@page { size: A4; margin: 20mm } h1 { font: 700 28pt Georgia }</style></head><body><h1>Hello, PDF</h1></body></html>"
}
JSON{
"id": "Hq8vR2cT9xKmL4pW",
"object": "pdf",
"url": "https://api.reflowpdf.com/v1/files/Hq8vR2cT9xKmL4pW/Hello.pdf",
"expires_at": "2026-11-03T10:22:31.000Z",
"filename": "Hello.pdf",
"pages": 1,
"bytes": 9612,
"mark": null,
"missing_variables": [],
"skipped_resources": []
}POST /v1/pdf/merge#
Merge PDFs
The parts' pages one after another in a new PDF. Each part is a PDF (stored for a link, in base64 or at an address) or a document printed first, all its pages or some (pages). Pages keep their content, links and form fields; the parts' outlines, tags and standard claims (PDF/A, PDF/UA) do not carry over — the result claims none.
Parameters
Idempotency-Keyheader · string- A key of yours (a UUID) that makes the request safe to repeat: within 24 hours the same key and body get the first result back, with nothing printed or charged twice. Another body under the same key is
422 idempotency_key_reused. Acceptheader ·"application/pdf"|"application/json"application/pdf(the default): the PDF itself.application/json: the PDF's link and facts (Pdf), the file kept 24 hours.
Body
partsarray of PdfPart required- The PDFs, in order: up to 50.
filenamestring- The merged PDF's file name (
merged.pdfwhen omitted).
Needs a key with the print scope (scopes).
Responses
- 200
- The merged PDF.
X-Page-CountIts pages.
- 201
- With
Accept: application/json: the PDF's link and facts. - 400
- The request is not valid: the problem names the field (
invalid_request); or a template that does not read: an expression, a tag or a filter it cannot parse (template_error). - 401
- No API key, or one not valid.
- 403
- A claim of the Pro and Max plans (PDF/A, PDF/X, PDF/UA-2) on another plan (
plan_required); a key without the scope the route asks for (insufficient_scope), or used from an address it is not kept to (ip_not_allowed). - 404
- A part names a file stored for a link that is not there, or expired (
file_not_found); or a template that is not (template_not_found). - 410
- The answer of an Idempotency-Key is no longer kept: a PDF or images an hour, a link 24 hours (
file_expired). - 413
- The body is over 15 MB, the document over the print's size, or a result over the 1 GB a file stored for a link may be (
result_too_large). - 415
- The body is not JSON.
- 422
- Not possible for this document (a claim it cannot keep, a page it does not have), a PDF that cannot be read (
invalid_pdf) or is encrypted without its password (pdf_encrypted), the layout did not settle, the Idempotency-Key was used with another request, or the page ofurlcould not be fetched (document_unreachable: not public, not HTML, over 15 MB or 20 s, or it answered an error), or theenginenamed prints here no more (engine_unavailable). - 429
- Too many requests of this account at once, or in the last minutes, or jobs not finished (
rate_limited); or the files it stores for links fill its plan's space: Free 256 MB, Pro and Max 2 GB (storage_quota). - 500
- Our error (
internal_error): give therequest_idto support. - 502
- The engine failed on our side (
render_failed): tried again, it may print. - 503
- The engine is busy (
engine_busy), the print took over its time limit (90 s for a request, 3 minutes for a job:render_timeout), or files cannot be stored for links right now (storage_full). SeeRetry-After.
curl -X POST https://api.reflowpdf.com/v1/pdf/merge \
-H "Authorization: Bearer $REFLOWPDF_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d @- <<'JSON'
{
"filename": "Invoice with terms",
"parts": [
{
"template_id": "invoice"
},
{
"pdf_url": "https://example.com/terms.pdf",
"pages": "1-2"
}
]
}
JSON{
"id": "Hq8vR2cT9xKmL4pW",
"object": "pdf",
"url": "https://api.reflowpdf.com/v1/files/Hq8vR2cT9xKmL4pW/Invoice%20with%20terms.pdf",
"expires_at": "2026-11-03T10:22:31.000Z",
"filename": "Invoice with terms.pdf",
"pages": 4,
"bytes": 241687,
"mark": null,
"missing_variables": [],
"skipped_resources": []
}POST /v1/pdf/split#
Split a PDF
A PDF's pages by ranges (each a new file), or every every pages: their links, and a ZIP of them, stored 24 hours.
Parameters
Idempotency-Keyheader · string- A key of yours (a UUID) that makes the request safe to repeat: within 24 hours the same key and body get the first result back, with nothing printed or charged twice. Another body under the same key is
422 idempotency_key_reused.
Body
filestring- A PDF of yours stored for a link: its
idfrom a JSON response (24 hours). pdfstring- A PDF's bytes, in base64 (within the 15 MB of a request).
pdf_urlstring- A public address of a PDF, fetched (up to 100 MB, 60 s).
htmlstring- Instead of a PDF: a document printed first, then split.
urlstring- Instead of
html: a public page, fetched and printed. template_idstring- Instead of
html: a template of the gallery or of your library, by its id. dataobject- The template's data (JSON); without it, the template's own sample data.
optionsOptionspasswordstring- The password of an encrypted PDF.
rangesarray of string- Each a new file:
["1-2", "3-"]. everyinteger- A new file every so many pages.
filenamestring- The files' base name.
Needs a key with the print scope (scopes).
Responses
- 201
- The files.
- 400
- The request is not valid: the problem names the field (
invalid_request); or a template that does not read: an expression, a tag or a filter it cannot parse (template_error). - 401
- No API key, or one not valid.
- 403
- A claim of the Pro and Max plans (PDF/A, PDF/X, PDF/UA-2) on another plan (
plan_required); a key without the scope the route asks for (insufficient_scope), or used from an address it is not kept to (ip_not_allowed). - 404
- A part names a file stored for a link that is not there, or expired (
file_not_found); or a template that is not (template_not_found). - 413
- The body is over 15 MB, the document over the print's size, or a result over the 1 GB a file stored for a link may be (
result_too_large). - 415
- The body is not JSON.
- 422
- Not possible for this document (a claim it cannot keep, a page it does not have), a PDF that cannot be read (
invalid_pdf) or is encrypted without its password (pdf_encrypted), the layout did not settle, the Idempotency-Key was used with another request, or the page ofurlcould not be fetched (document_unreachable: not public, not HTML, over 15 MB or 20 s, or it answered an error), or theenginenamed prints here no more (engine_unavailable). - 429
- Too many requests of this account at once, or in the last minutes, or jobs not finished (
rate_limited); or the files it stores for links fill its plan's space: Free 256 MB, Pro and Max 2 GB (storage_quota). - 500
- Our error (
internal_error): give therequest_idto support. - 503
- The engine is busy (
engine_busy), the print took over its time limit (90 s for a request, 3 minutes for a job:render_timeout), or files cannot be stored for links right now (storage_full). SeeRetry-After.
curl -X POST https://api.reflowpdf.com/v1/pdf/split \
-H "Authorization: Bearer $REFLOWPDF_API_KEY" \
-H "Content-Type: application/json" \
-d @- <<'JSON'
{
"file": "Hq8vR2cT9xKmL4pW",
"ranges": [
"1",
"2-"
]
}
JSON{
"id": "spl_N3wq8sHkT2xV9mRp4LcB1a",
"object": "split",
"files": [
{
"id": "Hq8vR2cT9xKmL4pW",
"pages": "1",
"page_count": 1,
"url": "https://api.reflowpdf.com/v1/files/Hq8vR2cT9xKmL4pW/report-pages-1.pdf",
"filename": "report-pages-1.pdf",
"bytes": 48213
}
],
"archive": null,
"expires_at": "2026-11-03T10:22:31.000Z"
}POST /v1/pdf/compress#
Compress a PDF
The PDF written again losslessly: its streams compressed anew, its objects in object streams, resources no page uses removed. It is never larger than it was, unless linearized for fast web view (its hint tables, a few KB). Its images stay as they are.
Parameters
Idempotency-Keyheader · string- A key of yours (a UUID) that makes the request safe to repeat: within 24 hours the same key and body get the first result back, with nothing printed or charged twice. Another body under the same key is
422 idempotency_key_reused. Acceptheader ·"application/pdf"|"application/json"application/pdf(the default): the PDF itself.application/json: the PDF's link and facts (Pdf), the file kept 24 hours.
Body
filestring- A PDF of yours stored for a link: its
idfrom a JSON response (24 hours). pdfstring- A PDF's bytes, in base64 (within the 15 MB of a request).
pdf_urlstring- A public address of a PDF, fetched (up to 100 MB, 60 s).
htmlstring- Instead of a PDF: a document printed first, then compressed.
urlstring- Instead of
html: a public page, fetched and printed. template_idstring- Instead of
html: a template of the gallery or of your library, by its id. dataobject- The template's data (JSON); without it, the template's own sample data.
optionsOptionspasswordstring- The password of an encrypted PDF.
linearizeboolean- Fast web view: its first page shows before the rest has arrived. Default
false. filenamestring- The compressed file's name.
Needs a key with the print scope (scopes).
Responses
- 200
- The compressed PDF.
X-Page-CountIts pages.ReflowPDF-Bytes-BeforeIts size before.
- 201
- With
Accept: application/json: the PDF's link and facts. - 400
- The request is not valid: the problem names the field (
invalid_request); or a template that does not read: an expression, a tag or a filter it cannot parse (template_error). - 401
- No API key, or one not valid.
- 403
- A claim of the Pro and Max plans (PDF/A, PDF/X, PDF/UA-2) on another plan (
plan_required); a key without the scope the route asks for (insufficient_scope), or used from an address it is not kept to (ip_not_allowed). - 404
- A part names a file stored for a link that is not there, or expired (
file_not_found); or a template that is not (template_not_found). - 410
- The answer of an Idempotency-Key is no longer kept: a PDF or images an hour, a link 24 hours (
file_expired). - 413
- The body is over 15 MB, the document over the print's size, or a result over the 1 GB a file stored for a link may be (
result_too_large). - 415
- The body is not JSON.
- 422
- Not possible for this document (a claim it cannot keep, a page it does not have), a PDF that cannot be read (
invalid_pdf) or is encrypted without its password (pdf_encrypted), the layout did not settle, the Idempotency-Key was used with another request, or the page ofurlcould not be fetched (document_unreachable: not public, not HTML, over 15 MB or 20 s, or it answered an error), or theenginenamed prints here no more (engine_unavailable). - 429
- Too many requests of this account at once, or in the last minutes, or jobs not finished (
rate_limited); or the files it stores for links fill its plan's space: Free 256 MB, Pro and Max 2 GB (storage_quota). - 500
- Our error (
internal_error): give therequest_idto support. - 502
- The engine failed on our side (
render_failed): tried again, it may print. - 503
- The engine is busy (
engine_busy), the print took over its time limit (90 s for a request, 3 minutes for a job:render_timeout), or files cannot be stored for links right now (storage_full). SeeRetry-After.
curl -X POST https://api.reflowpdf.com/v1/pdf/compress \
-H "Authorization: Bearer $REFLOWPDF_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d @- <<'JSON'
{
"pdf_url": "https://example.com/report.pdf",
"linearize": true
}
JSON{
"id": "Hq8vR2cT9xKmL4pW",
"object": "pdf",
"url": "https://api.reflowpdf.com/v1/files/Hq8vR2cT9xKmL4pW/report.pdf",
"expires_at": "2026-11-03T10:22:31.000Z",
"filename": "report.pdf",
"pages": 12,
"bytes": 812044,
"mark": null,
"missing_variables": [],
"skipped_resources": [],
"bytes_before": 1290311
}GET /v1/templates#
List templates
The gallery's templates and your account's own (made in the editor and saved as templates), newest first among yours.
Parameters
qquery · string- Words in the name, description or category.
categoryquery ·"Finance"|"Sales"|"Business"|"HR & Legal"|"Government"|"Personal"|"Logistics"|"Health"|"Events"|"Marketing"|"Showcase"- Only this category (gallery).
sourcequery ·"gallery"|"library"galleryorlibrary(yours) only.limitquery · integer- Templates per page.
starting_afterquery · string- The id of the last template of the previous page.
Needs a key with the templates scope (scopes).
Responses
- 200
- A page of templates.
- 400
- The request is not valid: the problem names the field (
invalid_request); or a template that does not read: an expression, a tag or a filter it cannot parse (template_error). - 401
- No API key, or one not valid.
- 403
- A claim of the Pro and Max plans (PDF/A, PDF/X, PDF/UA-2) on another plan (
plan_required); a key without the scope the route asks for (insufficient_scope), or used from an address it is not kept to (ip_not_allowed). - 429
- Too many requests of this account at once, or in the last minutes, or jobs not finished (
rate_limited); or the files it stores for links fill its plan's space: Free 256 MB, Pro and Max 2 GB (storage_quota).
curl https://api.reflowpdf.com/v1/templates \
-H "Authorization: Bearer $REFLOWPDF_API_KEY"{
"object": "list",
"data": [
{
"id": "invoice",
"object": "template",
"source": "gallery",
"name": "B2B Invoice",
"description": "Professional B2B invoice with line items, VAT breakdown, totals, payment terms and bank details.",
"category": "Finance",
"paper": {
"size": "A4",
"orientation": "portrait"
}
},
{
"id": "lib_Kp3xQ9mT2vLa8RcW",
"object": "template",
"source": "library",
"name": "Our invoice",
"description": null,
"category": null,
"updated_at": "2026-10-30T14:02:11.000Z"
}
],
"has_more": false
}GET /v1/templates/{id}#
Get a template
A template's source, its sample data and the JSON Schema of its data: the shape to fill.
Parameters
idpath · string required- A gallery template's id (
invoice) or yours (lib_…).
Needs a key with the templates scope (scopes).
Responses
- 200
- The template.
- 401
- No API key, or one not valid.
- 403
- A claim of the Pro and Max plans (PDF/A, PDF/X, PDF/UA-2) on another plan (
plan_required); a key without the scope the route asks for (insufficient_scope), or used from an address it is not kept to (ip_not_allowed). - 404
- No such template (
template_not_found). - 429
- Too many requests of this account at once, or in the last minutes, or jobs not finished (
rate_limited); or the files it stores for links fill its plan's space: Free 256 MB, Pro and Max 2 GB (storage_quota).
curl https://api.reflowpdf.com/v1/templates/invoice \
-H "Authorization: Bearer $REFLOWPDF_API_KEY"{
"id": "donation-receipt",
"object": "template",
"source": "gallery",
"name": "Donation Receipt",
"description": "Charitable tax-deductible donation receipt with donor and statement.",
"category": "Finance",
"paper": {
"size": "A4",
"orientation": "portrait"
},
"fillable": true,
"html": "<!doctype html>\n<html lang=\"en\">…<h1>{{ org }}</h1>…",
"sample_data": {
"org": "Riverbank Children’s Foundation",
"receiptNo": "DR-2027-00418",
"date": "2027-03-30",
"donor": "Aoife Donnelly",
"amount": "250.00",
"currency": "EUR"
},
"data_schema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"org": {
"type": "string"
},
"receiptNo": {
"type": "string"
},
"date": {
"type": "string",
"format": "date"
},
"donor": {
"type": "string"
},
"amount": {
"type": "string"
},
"currency": {
"type": "string"
}
},
"required": [
"org",
"receiptNo",
"date",
"donor",
"amount",
"currency"
]
}
}POST /v1/templates/{id}/pdf#
Fill a template and print it
Fills the template with data (its sample data when none is given) and prints it on its paper. A template of yours designed on the page (not in Code) takes no data: it prints as designed.
Parameters
idpath · string required- The template's id: a gallery template's name, or
lib_…for one of your library. Idempotency-Keyheader · string- A key of yours (a UUID) that makes the request safe to repeat: within 24 hours the same key and body get the first result back, with nothing printed or charged twice. Another body under the same key is
422 idempotency_key_reused. Acceptheader ·"application/pdf"|"application/json"application/pdf(the default): the PDF itself.application/json: the PDF's link and facts (Pdf), the file kept 24 hours.
Body
dataobject- The values the template reads, in the shape of
data_schema(its sample data when omitted). filenamestring- The file's name: yours, else the document's
<title>, elsedocument. optionsOptionsenginestring- Pin the print to an engine version (
GET /v1/engines): the current one, or a previous one, kept printing until three newer engines have shipped and 30 days at most. Without it, the current engine.
Needs a key with the print scope (scopes).
Responses
- 200
- The PDF.
X-Page-CountPages printed (and counted to the plan).Content-DispositionThe file's name:filename, else the document's<title>.X-ReflowPDF-Markfree-allowance-usedwhen a Free account's pages without the mark are used up for the month.ReflowPDF-Missing-VariablesThe template's variables the data did not give (comma-separated, URL-encoded); printed empty.ReflowPDF-Missing-GlyphsThe characters no font had a glyph for (UTF-8, percent-encoded): printed as empty boxes; add a font that covers them.ReflowPDF-Missing-FontsThe font families the document named that no face answered (each percent-encoded, comma-separated): their text took the next family of its list.ReflowPDF-Skipped-ResourcesThe addresses the print went without (space-separated; as many as 2 KB holds, then+Nfor the rest; the JSON response lists them all).Idempotent-Replayedtruewhen this is the answer of an earlier request with the same Idempotency-Key.ReflowPDF-EngineThe engine version that printed it (GET /v1/engines).ReflowPDF-ScriptsWithoptions.javascript: what the document's scripts did: thescriptsobject of the JSON response, as percent-encoded JSON (run,errors,error_count,skipped,modules,stopped,console).
- 201
- With
Accept: application/json: the PDF's link and facts. - 400
- The request is not valid: the problem names the field (
invalid_request); or a template that does not read: an expression, a tag or a filter it cannot parse (template_error). - 401
- No API key, or one not valid.
- 403
- A claim of the Pro and Max plans (PDF/A, PDF/X, PDF/UA-2) on another plan (
plan_required); a key without the scope the route asks for (insufficient_scope), or used from an address it is not kept to (ip_not_allowed). - 404
- No such template (
template_not_found). - 410
- The answer of an Idempotency-Key is no longer kept: a PDF or images an hour, a link 24 hours (
file_expired). - 413
- The body is over 15 MB, the document over the print's size, or a result over the 1 GB a file stored for a link may be (
result_too_large). - 415
- The body is not JSON.
- 422
- Not possible for this document (a claim it cannot keep, a page it does not have), a PDF that cannot be read (
invalid_pdf) or is encrypted without its password (pdf_encrypted), the layout did not settle, the Idempotency-Key was used with another request, or the page ofurlcould not be fetched (document_unreachable: not public, not HTML, over 15 MB or 20 s, or it answered an error), or theenginenamed prints here no more (engine_unavailable). - 429
- Too many requests of this account at once, or in the last minutes, or jobs not finished (
rate_limited); or the files it stores for links fill its plan's space: Free 256 MB, Pro and Max 2 GB (storage_quota). - 500
- Our error (
internal_error): give therequest_idto support. - 502
- The engine failed on our side (
render_failed): tried again, it may print. - 503
- The engine is busy (
engine_busy), the print took over its time limit (90 s for a request, 3 minutes for a job:render_timeout), or files cannot be stored for links right now (storage_full). SeeRetry-After.
curl -X POST https://api.reflowpdf.com/v1/templates/invoice/pdf \
-H "Authorization: Bearer $REFLOWPDF_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d @- <<'JSON'
{
"filename": "INV-1042"
}
JSON{
"id": "Hq8vR2cT9xKmL4pW",
"object": "pdf",
"url": "https://api.reflowpdf.com/v1/files/Hq8vR2cT9xKmL4pW/INV-1042.pdf",
"expires_at": "2026-11-03T10:22:31.000Z",
"filename": "INV-1042.pdf",
"pages": 2,
"bytes": 184213,
"mark": null,
"missing_variables": [],
"skipped_resources": []
}POST /v1/images#
HTML to page images
The document printed, its pages as images made from the PDF itself, on white paper. One page returns the image; several return a ZIP (page-001.png, …); with Accept: application/json, their links (24 hours). Pages count to your plan as the images delivered.
Parameters
Idempotency-Keyheader · string- A key of yours (a UUID) that makes the request safe to repeat: within 24 hours the same key and body get the first result back, with nothing printed or charged twice. Another body under the same key is
422 idempotency_key_reused. Acceptheader · stringapplication/json: links to the images instead of their bytes.
Body
htmlstring- The whole HTML document.
urlstring- Instead of
html: the page's public http(s) address (ports 80/443). It is fetched anonymously (redirects followed, each checked; 20 s, 15 MB) and printed from where it was found (its relative addresses resolve there). dataobject- When given,
htmlis a template filled with these values first. filenamestring- The images' base name (else the document's <title>).
optionsOptionsenginestring- Pin the print to an engine version (
GET /v1/engines): the current one, or a previous one, kept printing until three newer engines have shipped and 30 days at most. Without it, the current engine. format"png"|"webp"- Both lossless; WebP is usually smaller. Default
"png". pagesarray of integer | string- The pages,
[1, 3]or"1-3,5"; every page when omitted (up to 200). dpinumber- Pixels per inch (72 is one per point). Default
150.
Needs a key with the print scope (scopes).
Responses
- 200
- One page: the image. Several: a ZIP of them (
page-001.png, …).X-Page-CountImages delivered (and counted to the plan).X-Document-PagesThe pages of the document.X-ReflowPDF-Markfree-allowance-usedwhen a Free account's pages without the mark are used up for the month.ReflowPDF-Missing-VariablesThe template's variables the data did not give (comma-separated, URL-encoded); printed empty.ReflowPDF-Missing-GlyphsThe characters no font had a glyph for (UTF-8, percent-encoded): printed as empty boxes; add a font that covers them.ReflowPDF-Missing-FontsThe font families the document named that no face answered (each percent-encoded, comma-separated): their text took the next family of its list.ReflowPDF-Skipped-ResourcesThe addresses the print went without (space-separated; as many as 2 KB holds, then+Nfor the rest; the JSON response lists them all).Idempotent-Replayedtruewhen this is the answer of an earlier request with the same Idempotency-Key.ReflowPDF-EngineThe engine version that printed it (GET /v1/engines).ReflowPDF-ScriptsWithoptions.javascript: what the document's scripts did: thescriptsobject of the JSON response, as percent-encoded JSON (run,errors,error_count,skipped,modules,stopped,console).
- 201
- With
Accept: application/json: the images' links. - 400
- The request is not valid: the problem names the field (
invalid_request); or a template that does not read: an expression, a tag or a filter it cannot parse (template_error). - 401
- No API key, or one not valid.
- 403
- A claim of the Pro and Max plans (PDF/A, PDF/X, PDF/UA-2) on another plan (
plan_required); a key without the scope the route asks for (insufficient_scope), or used from an address it is not kept to (ip_not_allowed). - 410
- The answer of an Idempotency-Key is no longer kept: a PDF or images an hour, a link 24 hours (
file_expired). - 413
- The body is over 15 MB, the document over the print's size, or a result over the 1 GB a file stored for a link may be (
result_too_large). - 415
- The body is not JSON.
- 422
- Not possible for this document (a claim it cannot keep, a page it does not have), a PDF that cannot be read (
invalid_pdf) or is encrypted without its password (pdf_encrypted), the layout did not settle, the Idempotency-Key was used with another request, or the page ofurlcould not be fetched (document_unreachable: not public, not HTML, over 15 MB or 20 s, or it answered an error), or theenginenamed prints here no more (engine_unavailable). - 429
- Too many requests of this account at once, or in the last minutes, or jobs not finished (
rate_limited); or the files it stores for links fill its plan's space: Free 256 MB, Pro and Max 2 GB (storage_quota). - 500
- Our error (
internal_error): give therequest_idto support. - 502
- The engine failed on our side (
render_failed): tried again, it may print. - 503
- The engine is busy (
engine_busy), the print took over its time limit (90 s for a request, 3 minutes for a job:render_timeout), or files cannot be stored for links right now (storage_full). SeeRetry-After.
curl -X POST https://api.reflowpdf.com/v1/images \
-H "Authorization: Bearer $REFLOWPDF_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d @- <<'JSON'
{
"html": "<h1>Hello</h1>",
"format": "png",
"pages": [
1
],
"dpi": 150
}
JSON{
"id": "img_9Qm2xT8vLp4rWs1dYbZaKa",
"object": "images",
"format": "png",
"dpi": 150,
"document_pages": 1,
"images": [
{
"page": 1,
"url": "https://api.reflowpdf.com/v1/files/Hq8vR2cT9xKmL4pW/document-page-1.png",
"filename": "document-page-1.png",
"width": 1241,
"height": 1754,
"bytes": 21877
}
],
"archive": null,
"expires_at": "2026-11-03T10:22:31.000Z",
"mark": null,
"missing_variables": [],
"skipped_resources": []
}POST /v1/templates/{id}/images#
Fill a template, its pages as images
Fills the template with data (its sample data when none is given) and returns its pages as images, as POST /v1/images does for HTML.
Parameters
idpath · string required- The template's id: a gallery template's name, or
lib_…for one of your library. Idempotency-Keyheader · string- A key of yours (a UUID) that makes the request safe to repeat: within 24 hours the same key and body get the first result back, with nothing printed or charged twice. Another body under the same key is
422 idempotency_key_reused.
Body
dataobject- The template's data (JSON); without it, the template's own sample data.
filenamestring- The file's name: yours, else the document's
<title>, elsedocument. optionsOptionsenginestring- Pin the print to an engine version (
GET /v1/engines): the current one, or a previous one, kept printing until three newer engines have shipped and 30 days at most. Without it, the current engine. format"png"|"webp"png(default) orwebp, lossless. Default"png".pagesarray of integer | string- Pages to draw:
[1, 3]or"1-3,5"; all when left out. dpinumber- Pixels per inch, 18 to 600 (150 by default; 72 is one pixel per point). Default
150.
Needs a key with the print scope (scopes).
Responses
- 200
- One page: the image. Several: a ZIP of them (
page-001.png, …).X-Page-CountImages delivered (and counted to the plan).X-Document-PagesThe pages of the document.X-ReflowPDF-Markfree-allowance-usedwhen a Free account's pages without the mark are used up for the month.ReflowPDF-Missing-VariablesThe template's variables the data did not give (comma-separated, URL-encoded); printed empty.ReflowPDF-Missing-GlyphsThe characters no font had a glyph for (UTF-8, percent-encoded): printed as empty boxes; add a font that covers them.ReflowPDF-Missing-FontsThe font families the document named that no face answered (each percent-encoded, comma-separated): their text took the next family of its list.ReflowPDF-Skipped-ResourcesThe addresses the print went without (space-separated; as many as 2 KB holds, then+Nfor the rest; the JSON response lists them all).Idempotent-Replayedtruewhen this is the answer of an earlier request with the same Idempotency-Key.ReflowPDF-EngineThe engine version that printed it (GET /v1/engines).ReflowPDF-ScriptsWithoptions.javascript: what the document's scripts did: thescriptsobject of the JSON response, as percent-encoded JSON (run,errors,error_count,skipped,modules,stopped,console).
- 201
- With
Accept: application/json: the images' links. - 400
- The request is not valid: the problem names the field (
invalid_request); or a template that does not read: an expression, a tag or a filter it cannot parse (template_error). - 401
- No API key, or one not valid.
- 403
- A claim of the Pro and Max plans (PDF/A, PDF/X, PDF/UA-2) on another plan (
plan_required); a key without the scope the route asks for (insufficient_scope), or used from an address it is not kept to (ip_not_allowed). - 404
- No such template (
template_not_found). - 410
- The answer of an Idempotency-Key is no longer kept: a PDF or images an hour, a link 24 hours (
file_expired). - 413
- The body is over 15 MB, the document over the print's size, or a result over the 1 GB a file stored for a link may be (
result_too_large). - 415
- The body is not JSON.
- 422
- Not possible for this document (a claim it cannot keep, a page it does not have), a PDF that cannot be read (
invalid_pdf) or is encrypted without its password (pdf_encrypted), the layout did not settle, the Idempotency-Key was used with another request, or the page ofurlcould not be fetched (document_unreachable: not public, not HTML, over 15 MB or 20 s, or it answered an error), or theenginenamed prints here no more (engine_unavailable). - 429
- Too many requests of this account at once, or in the last minutes, or jobs not finished (
rate_limited); or the files it stores for links fill its plan's space: Free 256 MB, Pro and Max 2 GB (storage_quota). - 500
- Our error (
internal_error): give therequest_idto support. - 502
- The engine failed on our side (
render_failed): tried again, it may print. - 503
- The engine is busy (
engine_busy), the print took over its time limit (90 s for a request, 3 minutes for a job:render_timeout), or files cannot be stored for links right now (storage_full). SeeRetry-After.
curl -X POST https://api.reflowpdf.com/v1/templates/invoice/images \
-H "Authorization: Bearer $REFLOWPDF_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d @- <<'JSON'
{
"pages": "1",
"dpi": 150
}
JSON{
"id": "img_9Qm2xT8vLp4rWs1dYbZaKa",
"object": "images",
"format": "png",
"dpi": 150,
"document_pages": 3,
"images": [
{
"page": 1,
"url": "https://api.reflowpdf.com/v1/files/Hq8vR2cT9xKmL4pW/Invoice%20INV-1042-page-1.png",
"filename": "Invoice INV-1042-page-1.png",
"width": 1241,
"height": 1754,
"bytes": 182344
}
],
"archive": null,
"expires_at": "2026-11-03T10:22:31.000Z",
"mark": null,
"missing_variables": [],
"skipped_resources": []
}POST /v1/layout#
Where everything lands
The document printed, and where everything landed: every page's box, and every element with an id on each page it is drawn on (a table split across pages is on each). Build an index, place a stamp, check that a block fits, from the engine's own placement. Counted as the print.
Parameters
Idempotency-Keyheader · string- A key of yours (a UUID) that makes the request safe to repeat: within 24 hours the same key and body get the first result back, with nothing printed or charged twice. Another body under the same key is
422 idempotency_key_reused.
Body
htmlstring- A whole HTML document, its CSS inline or linked.
urlstring- Instead of
html: the page's public http(s) address (ports 80/443). It is fetched anonymously (redirects followed, each checked; 20 s, 15 MB) and printed from where it was found (its relative addresses resolve there). dataobject- The template's data (JSON); without it, the template's own sample data.
optionsOptionsenginestring- Pin the print to an engine version (
GET /v1/engines): the current one, or a previous one, kept printing until three newer engines have shipped and 30 days at most. Without it, the current engine.
Needs a key with the print scope (scopes).
Responses
- 200
- The layout.
- 400
- The request is not valid: the problem names the field (
invalid_request); or a template that does not read: an expression, a tag or a filter it cannot parse (template_error). - 401
- No API key, or one not valid.
- 403
- A claim of the Pro and Max plans (PDF/A, PDF/X, PDF/UA-2) on another plan (
plan_required); a key without the scope the route asks for (insufficient_scope), or used from an address it is not kept to (ip_not_allowed). - 413
- The body is over 15 MB, the document over the print's size, or a result over the 1 GB a file stored for a link may be (
result_too_large). - 415
- The body is not JSON.
- 422
- Not possible for this document (a claim it cannot keep, a page it does not have), a PDF that cannot be read (
invalid_pdf) or is encrypted without its password (pdf_encrypted), the layout did not settle, the Idempotency-Key was used with another request, or the page ofurlcould not be fetched (document_unreachable: not public, not HTML, over 15 MB or 20 s, or it answered an error), or theenginenamed prints here no more (engine_unavailable). - 429
- Too many requests of this account at once, or in the last minutes, or jobs not finished (
rate_limited); or the files it stores for links fill its plan's space: Free 256 MB, Pro and Max 2 GB (storage_quota). - 500
- Our error (
internal_error): give therequest_idto support. - 502
- The engine failed on our side (
render_failed): tried again, it may print. - 503
- The engine is busy (
engine_busy), the print took over its time limit (90 s for a request, 3 minutes for a job:render_timeout), or files cannot be stored for links right now (storage_full). SeeRetry-After.
curl -X POST https://api.reflowpdf.com/v1/layout \
-H "Authorization: Bearer $REFLOWPDF_API_KEY" \
-H "Content-Type: application/json" \
-d @- <<'JSON'
{
"html": "<h1 id=\"intro\">Intro</h1><p id=\"totals\">…</p>"
}
JSON{
"object": "layout",
"unit": "pt",
"document_pages": 2,
"pages": [
{
"number": 1,
"width": 595.28,
"height": 841.89
},
{
"number": 2,
"width": 595.28,
"height": 841.89
}
],
"elements": [
{
"id": "totals",
"page": 2,
"x": 56.69,
"y": 120.5,
"width": 481.89,
"height": 64
}
],
"missing_variables": [],
"skipped_resources": []
}POST /v1/templates/{id}/layout#
Fill a template, where everything lands
Fills the template with data (its sample data when none is given), prints it, and returns where everything landed, as POST /v1/layout does for HTML.
Parameters
idpath · string required- The template's id: a gallery template's name, or
lib_…for one of your library. Idempotency-Keyheader · string- A key of yours (a UUID) that makes the request safe to repeat: within 24 hours the same key and body get the first result back, with nothing printed or charged twice. Another body under the same key is
422 idempotency_key_reused.
Body
dataobject- The template's data (JSON); without it, the template's own sample data.
optionsOptionsenginestring- Pin the print to an engine version (
GET /v1/engines): the current one, or a previous one, kept printing until three newer engines have shipped and 30 days at most. Without it, the current engine.
Needs a key with the print scope (scopes).
Responses
- 200
- The layout.
- 400
- The request is not valid: the problem names the field (
invalid_request); or a template that does not read: an expression, a tag or a filter it cannot parse (template_error). - 401
- No API key, or one not valid.
- 403
- A claim of the Pro and Max plans (PDF/A, PDF/X, PDF/UA-2) on another plan (
plan_required); a key without the scope the route asks for (insufficient_scope), or used from an address it is not kept to (ip_not_allowed). - 404
- No such template (
template_not_found). - 413
- The body is over 15 MB, the document over the print's size, or a result over the 1 GB a file stored for a link may be (
result_too_large). - 422
- Not possible for this document (a claim it cannot keep, a page it does not have), a PDF that cannot be read (
invalid_pdf) or is encrypted without its password (pdf_encrypted), the layout did not settle, the Idempotency-Key was used with another request, or the page ofurlcould not be fetched (document_unreachable: not public, not HTML, over 15 MB or 20 s, or it answered an error), or theenginenamed prints here no more (engine_unavailable). - 429
- Too many requests of this account at once, or in the last minutes, or jobs not finished (
rate_limited); or the files it stores for links fill its plan's space: Free 256 MB, Pro and Max 2 GB (storage_quota). - 503
- The engine is busy (
engine_busy), the print took over its time limit (90 s for a request, 3 minutes for a job:render_timeout), or files cannot be stored for links right now (storage_full). SeeRetry-After.
curl -X POST https://api.reflowpdf.com/v1/templates/invoice/layout \
-H "Authorization: Bearer $REFLOWPDF_API_KEY"{
"object": "layout",
"unit": "pt",
"document_pages": 2,
"pages": [
{
"number": 1,
"width": 595.28,
"height": 841.89
},
{
"number": 2,
"width": 595.28,
"height": 841.89
}
],
"elements": [
{
"id": "totals",
"page": 2,
"x": 56.69,
"y": 120.5,
"width": 481.89,
"height": 64
}
],
"missing_variables": [],
"skipped_resources": []
}GET /v1/output-intents#
List print conditions
The print conditions PDF/X can claim here (options.pdf_x.output_intent). Your own printer's profile goes with the request instead (options.pdf_x.profile).
Needs a key with the print scope (scopes).
Responses
- 200
- The print conditions.
- 401
- No API key, or one not valid.
- 403
- A claim of the Pro and Max plans (PDF/A, PDF/X, PDF/UA-2) on another plan (
plan_required); a key without the scope the route asks for (insufficient_scope), or used from an address it is not kept to (ip_not_allowed).
curl https://api.reflowpdf.com/v1/output-intents \
-H "Authorization: Bearer $REFLOWPDF_API_KEY"{
"object": "list",
"data": [
{
"id": "FOGRA39",
"object": "output_intent",
"info": "ISO Coated v2 (ECI)",
"color_space": "CMYK"
}
],
"has_more": true
}GET /v1/output-intents/{id}/profile#
Download a print condition's profile
The ICC profile of a print condition, as its publisher made it (ETag: its SHA-256), for an API key or a licensed @reflowpdf/engine (its license's token), from any page (CORS): the engine fetches the one a document names.
Parameters
idpath · string required- A print condition, as
GET /v1/output-intentslists it:FOGRA39.
An API key with the print scope, or a licensed engine's token.
Responses
- 200
- The profile.
- 401
- Neither an API key nor a license's token.
- 404
- No such print condition.
curl https://api.reflowpdf.com/v1/output-intents/FOGRA39/profile \
-H "Authorization: Bearer $REFLOWPDF_API_KEY" \
-o FOGRA39.iccGET /v1/fonts/{family}#
A family of the font catalogue
ReflowPDF's catalogue, the Google Fonts the API and the editor print with, for a licensed @reflowpdf/engine or an API key: a family's faces, each with its header (its OpenType header tables, cmap and hmtx, as a small sfnt) and where its bytes are. The engine asks for the families its document names that no face of its own answers, and fetches the faces its text draws with.
Parameters
familypath · string required- A family of the catalogue, as
font-familynames it:Inter,Noto Sans JP.
An API key with the print scope, or a licensed engine's token.
Responses
- 200
- The family.
- 401
- Neither an API key nor a license's token.
- 404
- No such family in the catalogue.
curl https://api.reflowpdf.com/v1/fonts/Inter \
-H "Authorization: Bearer $REFLOWPDF_API_KEY"{
"object": "font_family",
"family": "string",
"header_format": 1,
"faces": [
{
"id": "string",
"weight": 1,
"style": "normal",
"sha256": "string",
"bytes": 1,
"header": "string",
"url": "https://api.reflowpdf.com/v1/files/…"
}
]
}GET /v1/fonts/files/{id}#
A face of the font catalogue
A face's bytes (TrueType or WOFF2, ETag: its SHA-256), as its foundry publishes it; its licence (SIL OFL 1.1, Apache 2.0 or the Ubuntu Font Licence) is in its own name table.
Parameters
idpath · string required- A face's id, from its family's
faces.
An API key with the print scope, or a licensed engine's token.
Responses
- 200
- The face.
- 401
- Neither an API key nor a license's token.
- 404
- No such face.
curl https://api.reflowpdf.com/v1/fonts/files/aff10562c603409a49b7ef65 \
-H "Authorization: Bearer $REFLOWPDF_API_KEY" \
-o font.woff2POST /v1/jobs#
Print asynchronously
The same print as POST /v1/pdf or POST /v1/templates/{id}/pdf, done in the background: answers 202 at once; poll GET /v1/jobs/{id} or receive the job.succeeded / job.failed webhook.
Parameters
Idempotency-Keyheader · string- A key of yours (a UUID) that makes the request safe to repeat: within 24 hours the same key and body get the first result back, with nothing printed or charged twice. Another body under the same key is
422 idempotency_key_reused.
Body
htmlstring- The document to print (or
url, ortemplate_id). urlstring- Instead of
html: the page's public http(s) address (ports 80/443). It is fetched anonymously (redirects followed, each checked; 20 s, 15 MB) and printed from where it was found (its relative addresses resolve there). template_idstring- Instead of
html: a template of the gallery or of your library, by its id. dataobject- The template's data (JSON); without it, the template's own sample data.
filenamestring- The file's name: yours, else the document's
<title>, elsedocument. optionsOptionsenginestring- Pin the print to an engine version (
GET /v1/engines): the current one, or a previous one, kept printing until three newer engines have shipped and 30 days at most. Without it, the current engine. webhook_urlstring- An https URL that receives
job.succeeded/job.failed. metadataobject- Your own keys, returned with the job and its webhook.
uploadobject- Into your own storage: the job PUTs its file to this signed address once printed: an S3 presigned URL, a Google Cloud Storage signed URL, an Azure Blob SAS, R2, any https endpoint that takes a PUT. No credential of your storage is given to us.
outputobject- What the job delivers: a PDF (the default), its pages as images, or the layout.
Needs a key with the print scope (scopes).
Responses
- 202
- The job, queued.
LocationThe job's address.
- 400
- The request is not valid: the problem names the field (
invalid_request); or a template that does not read: an expression, a tag or a filter it cannot parse (template_error). - 401
- No API key, or one not valid.
- 403
- A claim of the Pro and Max plans (PDF/A, PDF/X, PDF/UA-2) on another plan (
plan_required); a key without the scope the route asks for (insufficient_scope), or used from an address it is not kept to (ip_not_allowed). - 404
- No such template (
template_not_found). - 409
- A request with this Idempotency-Key is still being done.
- 415
- The body is not JSON.
- 422
- Not possible for this document (a claim it cannot keep, a page it does not have), a PDF that cannot be read (
invalid_pdf) or is encrypted without its password (pdf_encrypted), the layout did not settle, the Idempotency-Key was used with another request, or the page ofurlcould not be fetched (document_unreachable: not public, not HTML, over 15 MB or 20 s, or it answered an error), or theenginenamed prints here no more (engine_unavailable). - 429
- Too many requests of this account at once, or in the last minutes, or jobs not finished (
rate_limited); or the files it stores for links fill its plan's space: Free 256 MB, Pro and Max 2 GB (storage_quota).
curl -X POST https://api.reflowpdf.com/v1/jobs \
-H "Authorization: Bearer $REFLOWPDF_API_KEY" \
-H "Content-Type: application/json" \
-d @- <<'JSON'
{
"template_id": "invoice",
"webhook_url": "https://example.com/hooks/reflowpdf",
"metadata": {
"order": "42"
}
}
JSON{
"id": "job_Qm9xT2nV8cLp4rWs1dYbZa",
"object": "job",
"status": "queued",
"created_at": "2026-11-02T10:22:30.114Z",
"started_at": null,
"finished_at": null,
"template_id": "invoice",
"webhook_url": "https://example.com/hooks/reflowpdf",
"metadata": {
"order": "42"
},
"result": null,
"error": null
}GET /v1/jobs#
List jobs
The account's jobs of the last 24 hours, newest first.
Parameters
statusquery ·"queued"|"running"|"succeeded"|"failed"- Only the jobs in this state.
limitquery · integer- How many to a page (1–100).
starting_afterquery · string- The last job id of the previous page.
Needs a key with the print scope (scopes).
Responses
- 200
- A page of jobs.
- 400
- The request is not valid: the problem names the field (
invalid_request); or a template that does not read: an expression, a tag or a filter it cannot parse (template_error). - 401
- No API key, or one not valid.
- 403
- A claim of the Pro and Max plans (PDF/A, PDF/X, PDF/UA-2) on another plan (
plan_required); a key without the scope the route asks for (insufficient_scope), or used from an address it is not kept to (ip_not_allowed).
curl https://api.reflowpdf.com/v1/jobs \
-H "Authorization: Bearer $REFLOWPDF_API_KEY"{
"object": "list",
"data": [
{
"id": "job_Qm9xT2nV8cLp4rWs1dYbZa",
"object": "job",
"status": "succeeded",
"created_at": "2026-11-02T10:22:30.114Z",
"started_at": "2026-11-02T10:22:30.120Z",
"finished_at": "2026-11-02T10:22:31.402Z",
"template_id": "invoice",
"webhook_url": "https://example.com/hooks/reflowpdf",
"metadata": {
"order": "42"
},
"result": {
"id": "Hq8vR2cT9xKmL4pW",
"object": "pdf",
"url": "https://api.reflowpdf.com/v1/files/Hq8vR2cT9xKmL4pW/Invoice%20INV-1042.pdf",
"expires_at": "2026-11-03T10:22:31.000Z",
"filename": "Invoice INV-1042.pdf",
"pages": 2,
"bytes": 184213,
"mark": null,
"missing_variables": [],
"skipped_resources": []
},
"error": null
}
],
"has_more": true
}GET /v1/jobs/{id}#
Get a job
A job of this account from the last 24 hours: its status, and when it is done its result (the PDF's link and facts, the images or the layout) or its error.
Parameters
idpath · string required- The job's id (
job_…).
Needs a key with the print scope (scopes).
Responses
- 200
- The job.
- 401
- No API key, or one not valid.
- 403
- A claim of the Pro and Max plans (PDF/A, PDF/X, PDF/UA-2) on another plan (
plan_required); a key without the scope the route asks for (insufficient_scope), or used from an address it is not kept to (ip_not_allowed). - 404
- No such job in this account, or it is over 24 hours old.
curl https://api.reflowpdf.com/v1/jobs/job_Qm9xT2nV8cLp4rWs1dYbZa \
-H "Authorization: Bearer $REFLOWPDF_API_KEY"{
"id": "job_Qm9xT2nV8cLp4rWs1dYbZa",
"object": "job",
"status": "succeeded",
"created_at": "2026-11-02T10:22:30.114Z",
"started_at": "2026-11-02T10:22:30.120Z",
"finished_at": "2026-11-02T10:22:31.402Z",
"template_id": "invoice",
"webhook_url": "https://example.com/hooks/reflowpdf",
"metadata": {
"order": "42"
},
"result": {
"id": "Hq8vR2cT9xKmL4pW",
"object": "pdf",
"url": "https://api.reflowpdf.com/v1/files/Hq8vR2cT9xKmL4pW/Invoice%20INV-1042.pdf",
"expires_at": "2026-11-03T10:22:31.000Z",
"filename": "Invoice INV-1042.pdf",
"pages": 2,
"bytes": 184213,
"mark": null,
"missing_variables": [],
"skipped_resources": []
},
"error": null
}POST /v1/jobs/{id}/webhook#
Deliver a job's webhook again
Send a finished job's event to its webhook_url again now, after your receiver was down or lost it. The response is the job, its webhook saying how the delivery went.
Parameters
idpath · string required- The job's id (
job_…).
Needs a key with the print scope (scopes).
Responses
- 200
- The job after the delivery.
- 401
- No API key, or one not valid.
- 403
- A claim of the Pro and Max plans (PDF/A, PDF/X, PDF/UA-2) on another plan (
plan_required); a key without the scope the route asks for (insufficient_scope), or used from an address it is not kept to (ip_not_allowed). - 404
- No such job in this account, or it is over 24 hours old.
- 409
- The job has no webhook (
no_webhook), is not finished (job_not_finished), or an attempt to deliver its event is under way (delivery_in_progress). - 429
- Too many requests of this account at once, or in the last minutes, or jobs not finished (
rate_limited); or the files it stores for links fill its plan's space: Free 256 MB, Pro and Max 2 GB (storage_quota).
curl -X POST https://api.reflowpdf.com/v1/jobs/job_Qm9xT2nV8cLp4rWs1dYbZa/webhook \
-H "Authorization: Bearer $REFLOWPDF_API_KEY"{
"id": "job_Qm9xT2nV8cLp4rWs1dYbZa",
"object": "job",
"status": "succeeded",
"created_at": "2026-11-02T10:22:30.114Z",
"started_at": "2026-11-02T10:22:30.120Z",
"finished_at": "2026-11-02T10:22:31.402Z",
"template_id": "invoice",
"webhook_url": "https://example.com/hooks/reflowpdf",
"metadata": {
"order": "42"
},
"result": {
"id": "Hq8vR2cT9xKmL4pW",
"object": "pdf",
"url": "https://api.reflowpdf.com/v1/files/Hq8vR2cT9xKmL4pW/Invoice%20INV-1042.pdf",
"expires_at": "2026-11-03T10:22:31.000Z",
"filename": "Invoice INV-1042.pdf",
"pages": 2,
"bytes": 184213,
"mark": null,
"missing_variables": [],
"skipped_resources": []
},
"error": null
}GET /v1/webhook-secret#
Get the webhook secret
The secret with which your account's webhooks are signed (ReflowPDF-Signature). For 24 hours after a rotation, deliveries are signed with the previous secret too (a second v1).
Needs a key with the account scope (scopes).
Responses
- 200
- The secret.
- 401
- No API key, or one not valid.
- 403
- A claim of the Pro and Max plans (PDF/A, PDF/X, PDF/UA-2) on another plan (
plan_required); a key without the scope the route asks for (insufficient_scope), or used from an address it is not kept to (ip_not_allowed).
curl https://api.reflowpdf.com/v1/webhook-secret \
-H "Authorization: Bearer $REFLOWPDF_API_KEY"{
"object": "webhook_secret",
"secret": "whsec_3vK9…",
"rotated_at": null,
"previous_expires_at": null
}POST /v1/webhook-secret/rotate#
Rotate the webhook secret
A new secret now. For 24 hours deliveries carry a signature with each (the new and the previous) while your receivers move to the new one.
Needs a key with the account scope (scopes).
Responses
- 200
- The new secret.
- 401
- No API key, or one not valid.
- 403
- A claim of the Pro and Max plans (PDF/A, PDF/X, PDF/UA-2) on another plan (
plan_required); a key without the scope the route asks for (insufficient_scope), or used from an address it is not kept to (ip_not_allowed).
curl -X POST https://api.reflowpdf.com/v1/webhook-secret/rotate \
-H "Authorization: Bearer $REFLOWPDF_API_KEY"{
"object": "webhook_secret",
"secret": "whsec_3vK9…",
"rotated_at": null,
"previous_expires_at": null
}GET /v1/usage#
Get usage
The account's plan and this period: pages printed without the mark and what is left, AI pages, the files stored for links, and the rate of prints (also on every response as RateLimit-*).
Needs a key with the account scope (scopes).
Responses
- 200
- The usage.
- 401
- No API key, or one not valid.
- 403
- A claim of the Pro and Max plans (PDF/A, PDF/X, PDF/UA-2) on another plan (
plan_required); a key without the scope the route asks for (insufficient_scope), or used from an address it is not kept to (ip_not_allowed).
curl https://api.reflowpdf.com/v1/usage \
-H "Authorization: Bearer $REFLOWPDF_API_KEY"{
"object": "usage",
"plan": "free",
"status": null,
"period_resets_at": "2026-12-01T00:00:00+00:00",
"pages_printed": 12,
"pages_without_mark": {
"limit": 50,
"used": 12,
"remaining": 38
},
"api_pages": null,
"ai_pages": {
"quota": 10,
"used": 0,
"top_up": 0,
"remaining": 10
},
"files": {
"bytes": 1048576,
"limit_bytes": 268435456
},
"rate": {
"limit": 300,
"remaining": 298,
"reset": 431,
"window": 600,
"concurrent": 2,
"active": 0
}
}GET /v1/engines#
List engine versions
The engine versions a print may be pinned to (engine): the current one, and the previous ones, each kept printing until three newer engines have shipped, 30 days at most. Public, from any page.
Public: no key needed, from any page.
Responses
- 200
- The versions.
curl https://api.reflowpdf.com/v1/engines{
"object": "list",
"has_more": false,
"data": [
{
"object": "engine",
"version": "af4ba3e3b",
"status": "current",
"available_until": null
},
{
"object": "engine",
"version": "866470307",
"status": "previous",
"superseded_at": "2026-11-01T06:13:22.000Z",
"available_until": "2026-12-01T06:13:22.000Z"
}
]
}GET /v1/status#
The status of the service
What was measured every minute: each part of the service (the API, printing, the editor, the MCP server, the docs) now, its last 90 days day by day, and its incidents: two minutes or more of failed checks in a row. Public, from any page. The page: https://api.reflowpdf.com/docs/status/.
Public: no key needed, from any page.
Responses
- 200
- The status.
curl https://api.reflowpdf.com/v1/status{
"object": "status",
"checked_at": "2026-11-01T10:22:31.000Z",
"interval_seconds": 1,
"status": "operational",
"components": [
{
"id": "string",
"name": "string",
"description": "string",
"status": "operational",
"uptime_90d": null,
"latency_ms_24h": {
"p50": 1,
"p95": 1
},
"days": [
{
"date": "string",
"measured": 1,
"up": 1,
"uptime": null
}
]
}
],
"incidents": [
{
"component": "string",
"name": "string",
"started_at": "2026-11-01T10:22:31.000Z",
"ended_at": "2026-11-01T10:22:31.000Z",
"minutes": 1,
"error": "string",
"no_data_after": "2026-11-01T10:22:31.000Z"
}
]
}GET /v1/engine/license#
Get an engine license token
The signed token of an engine license, which @reflowpdf/engine checks offline (setLicense). By the license's key alone (public, written into your page; the engine package asks for it itself) the token is valid on the license's sites. With the API key of the license's owner it is also valid where there is no page (Node, Deno, Bun, a desktop app). A token lasts until the paid period ends and a week's grace, 42 days at most: ask again when it nears its end. Allowed from any origin (CORS).
Parameters
keyquery · string required- The license's key (
rpdfl_…), given with the license.
Public: no key needed, from any page.
Responses
- 200
- The token.
- 401
- No API key, or one not valid.
- 402
- The license is not paid for, or its subscription has ended.
- 404
- No license has this key.
curl "https://api.reflowpdf.com/v1/engine/license?key=rpdfl_…" \
-H "Authorization: Bearer $REFLOWPDF_API_KEY"{
"object": "engine_license_token",
"token": "rpdfl1.eyJ2IjoxLCJraWQiOiJrMSIsImlkIjoibGljXzh…",
"license": "lic_8Jq2vX0mT4nR7pW1sYc3Ka",
"licensee": "Northwind Studio Ltd",
"domains": [
"northwind.studio",
"*.northwind.studio"
],
"server": false,
"expires_at": "2026-12-09T10:00:00.000Z"
}GET /v1/files/{id}/{filename}#
Download a file
A PDF, an image or a ZIP of images stored for a link (Accept: application/json, a job, an Idempotency-Key). Its address is its key: keep it private; it works for 24 hours, unless its account deletes it.
Parameters
idpath · string required- The file's id, from its link.
filenamepath · string required- The file's name, as its link gives it.
Needs a key with the print scope (scopes).
Responses
- 200
- The file.
- 404
- No such file of this account, or it expired (a file is kept 24 hours).
curl https://api.reflowpdf.com/v1/files/Hq8vR2cT9xKmL4pW/Q3%20report.pdf \
-o "Q3 report.pdf"DELETE /v1/files/{id}#
Delete a file
Delete a file of your account before its 24 hours: its link stops working, and its space counts no more.
Parameters
idpath · string required- The file's id, from its link.
Needs a key with the print scope (scopes).
Responses
- 200
- Deleted.
- 401
- No API key, or one not valid.
- 403
- A claim of the Pro and Max plans (PDF/A, PDF/X, PDF/UA-2) on another plan (
plan_required); a key without the scope the route asks for (insufficient_scope), or used from an address it is not kept to (ip_not_allowed). - 404
- No such file of this account, or it expired (a file is kept 24 hours).
curl -X DELETE https://api.reflowpdf.com/v1/files/Hq8vR2cT9xKmL4pW \
-H "Authorization: Bearer $REFLOWPDF_API_KEY"{
"id": "string",
"object": "file",
"deleted": true
}Objects
FontFamily
object"font_family"required- Always
font_family. familystring required- The family's name, as a document's
font-familynames it. header_formatinteger required- 1: the faces' headers as small sfnt files.
facesarray of object required- Its faces: each with its weight, style, SHA-256 and its header (the OpenType tables an engine needs to lay text out before it fetches the face).
Options
How the document is printed: every capability of the engine. Each is optional; a wrong value is a 400 naming it.
paperPaperpdf_ua1|2- Claim PDF/UA: 1 (ISO 14289-1, PDF 1.7) or 2 (ISO 14289-2, PDF 2.0; Pro and Max). Every PDF is tagged unless
tagged: false. pdf_a"3a"|"1b"- Claim PDF/A (Pro and Max):
3a: ISO 19005-3, level A (tagged, with PDF/UA-1);1b: ISO 19005-1, level B (PDF 1.4: transparency flattened to opaque images, text stays selectable). A document that cannot keep the claim is a 422 with the reason. pdf_xPdfXtaggedboolean- A tagged PDF (structure for screen readers and reflow).
false: a smaller untagged file; not withpdf_uaorpdf_a: "3a". Defaulttrue. titlestring- The PDF's title (else the document's
<title>, else its first<h1>). langstring- The document's language when its
<html lang>names none (BCP 47). metadataobject- Over the document's own
<meta name="author|description|keywords">. header_footerHeaderFooterwatermarkWatermarkencryptionEncryptionattachmentsarray of Attachment- Files embedded in the PDF (up to 10 MB together). With
pdf_a: "3a"they are PDF/A-3 associated files; not withpdf_a: "1b"orpdf_x, whose standards forbid embedded files. compression"fast"|"default"|"smallest"- Lossless: how hard streams are compressed. Images are never resampled. Default
"default". object_streamsboolean- Pack objects into object streams (smaller files).
false: a classic cross-reference table for readers older than PDF 1.5. Defaulttrue. color_scheme"light"|"dark"- The answer to
prefers-color-scheme. Default"light". default_font_sizestring- The size of CSS
medium: the document's base font size. Default"12pt". print_scalenumber- Print the document shrunk by this factor.
shrink_to_fitboolean- Shrink a document wider than the paper to fit it, as browsers do. Off by default: lengths stay physical. Default
false. base_cssstring- CSS of yours below the document's own (user-agent origin): defaults the document may override.
input_format"html"|"xhtml"xhtml: parse the document as XML. Default"html".base_urlstring- Where the document's relative addresses point (an http(s) URL): the document's
<base href>unless it names its own. javascriptboolean- Run the document's scripts before it prints, over the engine's own document, its layout answering what they measure; the response's
scriptssays what they did. https://api.reflowpdf.com/docs/javascript/ Defaultfalse. allow_remoteboolean- Fetch the document's https/http images, stylesheets and fonts (public addresses only).
false: print with what it carries. Defaulttrue. max_pagesinteger- Print at most this many pages; the rest is left out.
PdfX
Claim PDF/X for a print condition (Pro and Max): its colours, boxes and output intent: a print-ready file.
standard"x-4"|"x-1a"x-4: ISO 15930-7 (PDF 1.6, transparency and RGB kept);x-1a: ISO 15930-4 (PDF 1.4, all colour converted to the condition's inks, transparency flattened; with a CMYK condition). Default"x-4".output_intentstring required- A print condition of
GET /v1/output-intents(e.g.FOGRA39), or the name of your ownprofile. profilestring- Your printer's characterization: an ICC output profile (class
prtr; gray, RGB or CMYK; up to 8 MB), in base64.
Watermark
A stamp on every page: a text, or an image. Drawn behind the content unless above; marked as an artifact in a tagged PDF.
textstring- The watermark's text.
imagestring- An https URL or a data: URL of an image (instead of
text). image_widthnumber- The image's drawn size in points, with
image_height(else its natural size at 96 dpi). image_heightnumber- The image's drawn height in points, with
image_width. font_sizenumber- Points. Default
60. colorstring- A CSS colour.
opacitynumber- From 0 (invisible) to 1 (opaque). Default
0.08. anglenumber- Degrees, counter-clockwise. Default
-45. aboveboolean- Over the content instead of under it. Default
false. tileboolean- Repeat the stamp across the page. Default
false. tile_spacingarray of number- [x, y] pitch of the tiles, points.
positionobject- One stamp here (points from the page's top-left) instead of the centre.
Encryption
Encrypt the PDF (AES-256 by default, ISO 32000-2). Not with PDF/A or PDF/X, whose standards forbid it.
user_passwordstring- Asked to open the file; empty or omitted, it opens without one, with the permissions below.
owner_passwordstring required- Lifts the permissions.
permissionsarray of"print"|"print-high"|"modify"|"copy"|"annotate"|"fill-forms"|"assemble"- What a reader may do; what is not listed is not allowed. Extraction for accessibility (screen readers) is always allowed (ISO 32000-2, PDF/UA).
algorithm"aes-256"|"rc4-128"rc4-128only for readers older than Acrobat 9. Default"aes-256".
Attachment
filenamestring required- The attached file's name.
contentstring required- The file's bytes, base64.
mime_typestring- Its media type.
descriptionstring- A line a PDF reader shows beside it.
relationship"data"|"source"|"alternative"|"supplement"|"unspecified"- How the file relates to the document (PDF/A-3
AFRelationship). Default"unspecified". elementstring- The
idof the element the file belongs to (a table's data, say); the document when omitted.
Paper
The paper where the document's CSS names none, as a user-agent @page rule: each property the document's own @page declares wins over it (its size, its margins). Without either: A4 portrait, 20 mm.
sizestring- A3, A4, A5, B4, B5, Letter, Legal, Ledger, Tabloid, or two lengths, "210mm 297mm". Default
"A4". orientation"portrait"|"landscape"portraitorlandscape. Default"portrait".marginstring- A CSS margin of lengths. Default
"20mm".
PdfRequest
htmlstring- The whole HTML document, with its <style>. Images and fonts by https URL or data: URI. Up to 15 MB.
urlstring- Instead of
html: the page's public http(s) address (ports 80/443). It is fetched anonymously (redirects followed, each checked; 20 s, 15 MB) and printed from where it was found (its relative addresses resolve there). dataobject- When given,
htmlis a template filled with these values first. filenamestring- The PDF's file name (else the document's <title>).
optionsOptionsenginestring- Pin the print to an engine version (
GET /v1/engines): the current one, or a previous one, kept printing until three newer engines have shipped and 30 days at most. Without it, the current engine.
TemplatePdfRequest
dataobject- The values the template reads, in the shape of
data_schema(its sample data when omitted). filenamestring- The file's name: yours, else the document's
<title>, elsedocument. optionsOptionsenginestring- Pin the print to an engine version (
GET /v1/engines): the current one, or a previous one, kept printing until three newer engines have shipped and 30 days at most. Without it, the current engine.
ImagesRequest
htmlstring- The whole HTML document.
urlstring- Instead of
html: the page's public http(s) address (ports 80/443). It is fetched anonymously (redirects followed, each checked; 20 s, 15 MB) and printed from where it was found (its relative addresses resolve there). dataobject- When given,
htmlis a template filled with these values first. filenamestring- The images' base name (else the document's <title>).
optionsOptionsenginestring- Pin the print to an engine version (
GET /v1/engines): the current one, or a previous one, kept printing until three newer engines have shipped and 30 days at most. Without it, the current engine. format"png"|"webp"- Both lossless; WebP is usually smaller. Default
"png". pagesarray of integer | string- The pages,
[1, 3]or"1-3,5"; every page when omitted (up to 200). dpinumber- Pixels per inch (72 is one per point). Default
150.
TemplateImagesRequest
dataobject- The template's data (JSON); without it, the template's own sample data.
filenamestring- The file's name: yours, else the document's
<title>, elsedocument. optionsOptionsenginestring- Pin the print to an engine version (
GET /v1/engines): the current one, or a previous one, kept printing until three newer engines have shipped and 30 days at most. Without it, the current engine. format"png"|"webp"png(default) orwebp, lossless. Default"png".pagesarray of integer | string- Pages to draw:
[1, 3]or"1-3,5"; all when left out. dpinumber- Pixels per inch, 18 to 600 (150 by default; 72 is one pixel per point). Default
150.
LayoutRequest
htmlstring- A whole HTML document, its CSS inline or linked.
urlstring- Instead of
html: the page's public http(s) address (ports 80/443). It is fetched anonymously (redirects followed, each checked; 20 s, 15 MB) and printed from where it was found (its relative addresses resolve there). dataobject- The template's data (JSON); without it, the template's own sample data.
optionsOptionsenginestring- Pin the print to an engine version (
GET /v1/engines): the current one, or a previous one, kept printing until three newer engines have shipped and 30 days at most. Without it, the current engine.
TemplateLayoutRequest
dataobject- The template's data (JSON); without it, the template's own sample data.
optionsOptionsenginestring- Pin the print to an engine version (
GET /v1/engines): the current one, or a previous one, kept printing until three newer engines have shipped and 30 days at most. Without it, the current engine.
Images
The pages as images, each stored for a link for 24 hours, and the ZIP of them when there are several.
scriptsScriptsenginestring- The engine version that printed it.
idstring- Its id.
object"images"required- Always
images. format"png"|"webp"required- The images' format.
dpinumber- The pixels per inch they were drawn at.
document_pagesinteger required- The pages of the document.
imagesarray of object required- Each page drawn: its number, link, file name, size in pixels and bytes.
archiveobject | null- With several pages, a ZIP of them: its link and name; else
null. expires_atstring | null- When the files stop answering at their links (24 hours after they were made), unless deleted first.
markstring | nullfree-allowance-usedwhen the pages carry the ReflowPDF mark (a Free account past its 50 a month); elsenull.missing_variablesarray of string- The template's variables the data did not give, printed empty.
skipped_resourcesarray of string- The addresses the print went without: an image, stylesheet or font that could not be fetched.
missing_glyphsstring- The characters no font had a glyph for, printed as empty boxes; add a font that covers them (
@font-face). missing_fontsarray of string- The font families the document named that no face here answered: their text took the next family of its list. Give them with
@font-face.
Layout
Where everything landed: every page's box and every element with an id on each page it is drawn on: its rectangle there, from the page's top-left corner.
scriptsScriptsenginestring- The engine version that printed it.
object"layout"required- Always
layout. unit"pt"required- Every length is in points (1/72 inch), from the page's top-left corner.
document_pagesinteger- The pages of the document.
pagesarray of object required- Each page's number and size.
elementsarray of object required- Each element with an
id, on each page it is drawn on: its rectangle there. markstring | nullfree-allowance-usedwhen the pages carry the ReflowPDF mark (a Free account past its 50 a month); elsenull.missing_variablesarray of string- The template's variables the data did not give, printed empty.
skipped_resourcesarray of string- The addresses the print went without: an image, stylesheet or font that could not be fetched.
missing_glyphsstring- The characters no font had a glyph for, printed as empty boxes; add a font that covers them (
@font-face). missing_fontsarray of string- The font families the document named that no face here answered: their text took the next family of its list. Give them with
@font-face.
OutputIntent
idstring required- The
output_intentto name. object"output_intent"required- Always
output_intent. infostring- The profile's description (its ICC
desc). color_space"Gray"|"RGB"|"CMYK"required- The colour space of the condition's profile.
profile_urlstring- Its ICC profile, unaltered; public, from any page.
OutputIntentList
object"list"required- Always
list. dataarray of OutputIntent required- The print conditions ReflowPDF provides, by name.
has_moreboolean- Always
false: the whole list is here.
Scripts
What the document's scripts did (options.javascript).
runinteger- Classic scripts run, in the document's order.
errorsarray of string- Their uncaught errors, each with its script (
script #3, or its address), up to 50. error_countinteger- How many uncaught errors there were (the list keeps 50).
skippedarray of string- External scripts that could not be fetched (or with the network closed,
allow_remote: false). modulesarray of string- Module scripts (
type="module"), which are not run. stoppedstring | null- The limit that stopped them: their steps, their processor time or 30 s.
consolearray of string- What they wrote to the console,
level: text, up to 100.
EngineList
object"list"required- Always
list. has_moreboolean- Always
false: the whole list is here. dataarray of object required- The current engine and the previous ones a print may be pinned to.
Status
object"status"required- Always
status. checked_atstring | null- When the last check ran.
interval_secondsinteger- How often the parts are checked.
status"operational"|"degraded"|"unknown"requiredunknown: nothing measured in the last 3 minutes.componentsarray of object required- Each part: its state now and its days.
incidentsarray of object required- Two minutes or more of failed checks in a row, newest first.
PdfPart
One PDF: file (the id of a PDF of yours stored for a link), pdf (its bytes in base64, within the 15 MB of a request), pdf_url (a public http(s) address of one, up to 100 MB), or a document printed first, as POST /v1/pdf prints it (html, url or template_id, with data, options, filename).
filestring- A PDF of yours stored for a link: its
idfrom a JSON response (24 hours). pdfstring- A PDF's bytes, in base64 (within the 15 MB of a request).
pdf_urlstring- A public address of a PDF, fetched (up to 100 MB, 60 s).
htmlstring- A document printed first, as
POST /v1/pdfprints it. urlstring- Instead of
html: a public page, fetched and printed. template_idstring- Instead of
html: a template of the gallery or of your library, by its id. dataobject- The data of
htmlortemplate_idas a template. optionsOptionsfilenamestring- The name the printed part takes.
pagesstring- Some of its pages, in this order:
"1-3,5,8-"(8-: to the end). passwordstring- An encrypted PDF's password.
enginestring- Pin the print to an engine version (
GET /v1/engines): the current one, or a previous one, kept printing until three newer engines have shipped and 30 days at most. Without it, the current engine.
MergeRequest
partsarray of PdfPart required- The PDFs, in order: up to 50.
filenamestring- The merged PDF's file name (
merged.pdfwhen omitted).
SplitRequest
The PDF (as a PdfPart, without pages) and either ranges or every.
filestring- A PDF of yours stored for a link: its
idfrom a JSON response (24 hours). pdfstring- A PDF's bytes, in base64 (within the 15 MB of a request).
pdf_urlstring- A public address of a PDF, fetched (up to 100 MB, 60 s).
htmlstring- Instead of a PDF: a document printed first, then split.
urlstring- Instead of
html: a public page, fetched and printed. template_idstring- Instead of
html: a template of the gallery or of your library, by its id. dataobject- The template's data (JSON); without it, the template's own sample data.
optionsOptionspasswordstring- The password of an encrypted PDF.
rangesarray of string- Each a new file:
["1-2", "3-"]. everyinteger- A new file every so many pages.
filenamestring- The files' base name.
CompressRequest
The PDF (as a PdfPart, without pages), and linearize.
filestring- A PDF of yours stored for a link: its
idfrom a JSON response (24 hours). pdfstring- A PDF's bytes, in base64 (within the 15 MB of a request).
pdf_urlstring- A public address of a PDF, fetched (up to 100 MB, 60 s).
htmlstring- Instead of a PDF: a document printed first, then compressed.
urlstring- Instead of
html: a public page, fetched and printed. template_idstring- Instead of
html: a template of the gallery or of your library, by its id. dataobject- The template's data (JSON); without it, the template's own sample data.
optionsOptionspasswordstring- The password of an encrypted PDF.
linearizeboolean- Fast web view: its first page shows before the rest has arrived. Default
false. filenamestring- The compressed file's name.
Split
idstring- Its id.
object"split"required- Always
split. filesarray of object required- Each new file: its pages, link and name.
archiveobject | null- With several files, a ZIP of them; else
null. expires_atstring | null- When the files stop answering at their links (24 hours after they were made), unless deleted first.
enginestring- The engine version that printed its source, when it was printed in the same request.
JobRequest
Either html, url (with optional data) or template_id (with optional data).
htmlstring- The document to print (or
url, ortemplate_id). urlstring- Instead of
html: the page's public http(s) address (ports 80/443). It is fetched anonymously (redirects followed, each checked; 20 s, 15 MB) and printed from where it was found (its relative addresses resolve there). template_idstring- Instead of
html: a template of the gallery or of your library, by its id. dataobject- The template's data (JSON); without it, the template's own sample data.
filenamestring- The file's name: yours, else the document's
<title>, elsedocument. optionsOptionsenginestring- Pin the print to an engine version (
GET /v1/engines): the current one, or a previous one, kept printing until three newer engines have shipped and 30 days at most. Without it, the current engine. webhook_urlstring- An https URL that receives
job.succeeded/job.failed. metadataobject- Your own keys, returned with the job and its webhook.
uploadobject- Into your own storage: the job PUTs its file to this signed address once printed: an S3 presigned URL, a Google Cloud Storage signed URL, an Azure Blob SAS, R2, any https endpoint that takes a PUT. No credential of your storage is given to us.
outputobject- What the job delivers: a PDF (the default), its pages as images, or the layout.
scriptsScriptsenginestring- The engine version that printed it.
bytes_beforeinteger- Compress: its size before.
idstring required- Its id.
object"pdf"required- Always
pdf. urlstring required- The PDF, for 24 hours. Its address is its key.
expires_atstring required- When the files stop answering at their links (24 hours after they were made), unless deleted first.
filenamestring required- The file's name: yours, else the document's
<title>, elsedocument. pagesinteger required- Its pages (counted to the plan).
bytesinteger required- Its size in bytes.
markstring | nullfree-allowance-usedwhen printed with the ReflowPDF mark.missing_variablesarray of string- The template's variables the data did not give.
skipped_resourcesarray of string- Images, fonts or stylesheets that could not be fetched (printed without them).
missing_glyphsstring- The characters no font had a glyph for, printed as empty boxes; add a font that covers them (
@font-face). missing_fontsarray of string- The font families the document named that no face here answered: their text took the next family of its list. Give them with
@font-face.
Template
idstring required- The id to print it by: a gallery template's name, or
lib_…for one of your library. object"template"required- Always
template. source"gallery"|"library"requiredlibrary: made in your account's editor.namestring required- Its name.
descriptionstring | null- What it is, in a line (gallery templates).
categorystring | null- Its group in the gallery (gallery templates).
paperobject- The paper it prints on.
updated_atstring- When you last changed it (library templates).
TemplateDetail
idstring required- The id to print it by: a gallery template's name, or
lib_…for one of your library. object"template"required- Always
template. source"gallery"|"library"requiredlibrary: made in your account's editor.namestring required- Its name.
descriptionstring | null- What it is, in a line (gallery templates).
categorystring | null- Its group in the gallery (gallery templates).
paperobject- The paper it prints on.
updated_atstring- When you last changed it (library templates).
fillableboolean required- Whether it takes data (a template with
{{ … }}); one designed on the page prints as designed. htmlstring required- The template's source.
sample_dataobject | null- Example data: the shape to fill.
data_schemaobject | null- The JSON Schema (2020-12) of its data, read from the sample.
TemplateList
object"list"required- Always
list. dataarray of Template required- The templates of this page.
has_moreboolean required- Whether more items follow this page: ask again with
starting_afterset to the last id.
Job
idstring required- Its id.
object"job"required- Always
job. status"queued"|"running"|"succeeded"|"failed"required- A job waits for its account's turn (
queued, up to an hour) and survives our restarts; one that could not be run again fails withinterrupted. created_atstring required- When it was made.
started_atstring- When the print began;
nullwhile queued. finished_atstring- When it was done;
nulluntil then. template_idstring | null- The template it prints, if any.
webhook_urlstring | null- Where its event is sent, if anywhere.
outputobject- What the job delivers.
webhookobject- How its event was delivered (a job with a
webhook_url). metadataobject- Up to 20 keys of yours, returned with the job and its webhook.
errorobject | null- Why it failed (
code,title,detail);nullunless it did. uploadobject- How its file went into your storage (a job with an
upload). The job staysrunninguntil it is there or has failed.
EngineLicenseToken
object"engine_license_token"required- Always
engine_license_token. tokenstring required- Give it to the engine:
engine.setLicense(token).rpdfl1.<payload>.<Ed25519 signature>. licensestring required- The license's id.
licenseestring required- Who the license is billed to, as the token names them.
domainsarray of string required- The sites it prints on without the trial mark;
*.example.comnames the subdomains of example.com. serverboolean required- Also valid where there is no page (asked for with the owner's API key).
expires_atstring required- When the token ends: the paid period, and a week's grace.
WebhookSecret
object"webhook_secret"required- Always
webhook_secret. secretstring required- The secret webhooks are signed with (HMAC-SHA256).
rotated_atstring | null- When it was last rotated;
nullif never. previous_expires_atstring | null- Until when deliveries are also signed with the previous secret.
JobList
object"list"required- Always
list. dataarray of Job required- The jobs of this page, newest first.
has_moreboolean required- Whether more items follow this page: ask again with
starting_afterset to the last id.
Usage
object"usage"required- Always
usage. plan"free"|"pro"|"max"required- The account's plan.
statusstring | null- The subscription's state (
active,past_due, …);nullon Free. period_resets_atstring | null- When the month's pages begin again.
pages_printedinteger- Pages printed this period, the API's and the editor's.
pages_without_markobject- Of them, the ones without the ReflowPDF mark: a Free account's allowance (past it, pages carry the mark); a paid plan's are all.
api_pagesobject | null- The pages the API laid out this period on a paid plan: the plan's quota (Pro 1,000, Max 5,000), those used, those left, and those past the quota, billed at $5 per 1,000. A document's pages count, also when only some of them are asked as pictures.
nullon Free, whose API pages are its pages without the mark, and on a Pro or Max subscription started before 14 November 2026, which keeps every API page. ai_pagesobject- The AI pages of the plan: the month's quota, those used, and those bought on top.
filesobject- The space the files stored for links take, and the plan's limit.
rateobject | null- Where the account stands in its rate now: as the
RateLimit-*headers say.
WebhookEvent
idstring required- The event's id: handle one you have seen as done (a delivery can be repeated).
object"event"required- Always
event. type"job.succeeded"|"job.failed"requiredjob.succeededorjob.failed.createdinteger required- Unix seconds.
dataobject required- The job, as
GET /v1/jobs/{id}gives it.
Problem
RFC 9457 problem details.
typestring required- The page of the docs about this error.
titlestring required- The problem in a few words.
statusinteger required- The HTTP status.
detailstring- What happened and what to do.
code"invalid_request"|"invalid_json"|"template_not_fillable"|"invalid_html"|"template_error"|"unauthorized"|"invalid_api_key"|"license_inactive"|"plan_required"|"not_found"|"template_not_found"|"job_not_found"|"file_not_found"|"license_not_found"|"font_not_found"|"method_not_allowed"|"idempotency_in_progress"|"job_not_finished"|"no_webhook"|"delivery_in_progress"|"insufficient_scope"|"ip_not_allowed"|"license_required"|"document_unreachable"|"engine_unavailable"|"invalid_pdf"|"pdf_encrypted"|"file_expired"|"payload_too_large"|"document_too_large"|"result_too_large"|"unsupported_media_type"|"unfulfillable"|"render_failed"|"idempotency_key_reused"|"rate_limited"|"storage_quota"|"interrupted"|"internal_error"|"engine_busy"|"storage_full"|"render_timeout"required- Stable, machine-readable: https://api.reflowpdf.com/docs/errors/.
request_idstring required- Give it to support.