Verifiable documents
Every document Renderly generates is verifiable. At issuance time we compute the SHA-256 of the bytes and register the issuance. Later, anyone can prove that a file is intact and was generated by you — without having to take our word for it, by checking the bytes.
How it works
Verification is by content integrity. SHA-256 is a fingerprint of the file bytes: change a single byte and the hash changes completely. Because we keep the issuance hash, we can confirm whether a file in hand is exactly what was issued — or whether it was tampered with.
- 1Issuance. When rendering, we compute the SHA-256 of the delivered bytes and record an issuance (with organization, template, format and pages).
- 2Discreet seal. By default the output carries a verification seal — a QR pointing to the public page /verify/<id>.
- 3Verification. Later, send the file bytes to POST /api/verify. We recompute the hash and look for the matching issuance.
- 4Verdict. If the hash matches, the file is intact (verified) and we return the issuance metadata. If it does not match, it is not_found — tampered with or never issued by us.
The verification data in the render response
The response of /v1/render already carries everything that links the file to its issuance, in the headers:
HTTP/1.1 200 OK
Content-Type: application/pdf
X-Render-Ms: 842
X-Render-Bytes: 18234
X-Render-Engine: native
X-Renderly-Document-Hash: 3b2f9c...e41a
X-Renderly-Verify-Id: 9f1c2d34-...-a1b2
X-Renderly-Verify-Url: https://api.renderly.dev/verify/9f1c2d34-...-a1b2| Header | What for |
|---|---|
X-Renderly-Document-Hash | The SHA-256 of the bytes. Keep it for future checking. |
X-Renderly-Verify-Id | The issuance id; it composes the public verification URL. |
X-Renderly-Verify-Url | Direct link to the /verify/<id> page. |
X-Renderly-Document-Hash always comes in the success response.Verification endpoint
/api/verifyPublic, no authentication.The request body is the raw bytes of the file — not JSON, not base64, not multipart. We recompute the hash of those bytes and look for the issuance. It is this “check the file, not the URL” approach that makes verification tamper-proof: nobody has to trust the QR, only the content.
curl
curl -X POST https://api.renderly.dev/api/verify \
--data-binary @invoice.pdfJavaScript
import { readFile } from "node:fs/promises"
const bytes = await readFile("invoice.pdf")
const res = await fetch("https://api.renderly.dev/api/verify", {
method: "POST",
body: bytes, // the raw PDF BYTES — not JSON, not base64
})
const result = await res.json()
// { status: "verified", hash, issuance: { ... } }
console.log(result.status, result.issuance?.organization)Python
import requests
with open("invoice.pdf", "rb") as f:
bytes_ = f.read()
res = requests.post("https://api.renderly.dev/api/verify", data=bytes_, timeout=30)
print(res.json())Verification responses
Verified — status: verified
The hash matches a registered issuance. We return its metadata.
{
"status": "verified",
"hash": "3b2f9c...e41a",
"issuance": {
"id": "9f1c2d34-...-a1b2",
"issuedAt": "2026-06-15T13:42:08.512Z",
"organization": "Acme Inc",
"templateName": "Invoice",
"format": "PDF",
"pages": 2,
"docHash": "7a1e...c0"
}
}| issuance field | Meaning |
|---|---|
id | Issuance identifier (the same as in /verify/<id>). |
issuedAt | Issuance date and time (ISO 8601). |
organization | Name of the organization that issued it. |
templateName | Name of the template used (if any). |
format | PDF or PNG. |
pages | Number of pages (when applicable). |
docHash | Hash of the canonical document model (independent of the bytes). |
Not found — status: not_found
The hash does not match any issuance. This means one of two things: the file was tampered with after issuance, or was never generated by Renderly.
{
"status": "not_found",
"hash": "00ab...ff"
}| HTTP | status | Cause |
|---|---|---|
| 200 | verified | Bytes match an issuance. |
| 200 | not_found | Bytes do not match any issuance. |
| 400 | empty | No file sent in the body. |
| 413 | too_large | File larger than 25 MB. |
Public page /verify/<id>
Each issuance has a public page at /verify/<id>. It shows the issuance metadata (who issued it, when, template, format and the start of the hash) and offers an upload to check the bytes right there. It is the page the verification seal QR points to — any recipient of the document can open it and confirm provenance.
The verification seal
Every output carries a discreet verification seal — the Renderly mark + a QR pointing to the /verify/<id> page — and this is default and mandatory on every plan. It is the heart of Renderly: anyone can check that the document is authentic, without having to trust you. The watermark parameter is accepted for compatibility, but ignored.
For the full security and privacy posture (zero-retention, encryption, what we store), see Security & Trust.
Renderly