You need an API key and a template ID. Both come from the dashboard. Everything below runs against a public template, so you get a file back before you have built anything of your own.
1. Install
npm install @ireceipt.pro/js
Node 16 or newer. The package ships both ESM and CommonJS builds, with TypeScript declarations.
Note the dot in the scope. The installable name is
@ireceipt.pro/js. Some tools display scoped names with
the dot sanitised to a hyphen, so you may see
@ireceipt-pro/js written down — that one is not a real
package and npm install will fail on it.
2. Render something
import { IReceiptPRO } from "@ireceipt.pro/js";
import { writeFile } from "node:fs/promises";
const irp = new IReceiptPRO(process.env.IRECEIPT_API_KEY);
const pdf = await irp.createPdfFromPublicTemplate(
"invoice_universal_vzrt6k1s",
{
invoice: {
number: "13",
date: "2023-10-03",
table: {
headers: ["NAME", "PRICE", "QTY", "AMOUNT"],
rows: [
{ values: ["UX Services", "$100.00", "2", "$200.00"] },
{ values: ["Development Service", "$2000.00", "1", "$2000.00"] },
],
},
total: "$2200.00",
},
from: { companyName: "Your Company", lines: ["[email protected]"] },
to: { companyName: "Their Company", lines: ["Somewhere"] },
},
{ width: 796, height: 1126 }
);
await writeFile("invoice.pdf", Buffer.from(pdf));
CommonJS is the same call with a different import:
const { IReceiptPRO } = require("@ireceipt.pro/js");
That is the whole integration. There is no browser to launch, no worker pool, and no font package to install in your container.
3. The shape of every call
All eight methods take the same three arguments:
await irp.createPdfFromPublicTemplate(templateId, args, size);
| argument | required | what it is |
|---|---|---|
templateId | yes | from the dashboard, e.g. invoice_universal_vzrt6k1s |
args | yes | the values substituted into the template |
size | no |
{ width, height } in pixels. The default is A4
portrait, 796×1126.
|
The method name encodes the two choices — output format, and whether the template is a public one or your own:
| public template | your own template | |
|---|---|---|
createPdfFromPublicTemplate | createPdfFromPrivateTemplate | |
| PNG | createPngFromPublicTemplate | createPngFromPrivateTemplate |
| JPG | createJpgFromPublicTemplate | createJpgFromPrivateTemplate |
| WEBP | createWebpFromPublicTemplate | createWebpFromPrivateTemplate |
Each returns a promise resolving to the raw file bytes — a
Buffer on Node, an ArrayBuffer elsewhere.
Nothing is written to disk for you.
There is also a static constructor, if you prefer it:
const irp = IReceiptPRO.useApiKey(process.env.IRECEIPT_API_KEY);
4. Browse the templates before you call anything
Every public template has a sandbox page:
https://dashboard.ireceipt.pro/sandbox/public/<templateId>
Load it, read the field names off the
ARGUMENTS (JSON) block, and copy them into your
args. Faster than guessing the JSON shape from a code
sample.
Without the SDK
The SDK is a thin wrapper over one endpoint. If you are not on Node, call it directly:
curl -X POST https://api.ireceipt.pro/v1/pdf/public/invoice_universal_vzrt6k1s \
-H "Authorization: Bearer $IRECEIPT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"variables":{"invoice":{"number":"13","total":"$2200.00"}},"size":{"width":796,"height":1126}}' \
--output invoice.pdf
The path is /v1/{format}/{public|private}/{templateId},
where format is one of pdf, png,
jpg or webp. Your template values go under
variables — note that the SDK calls this argument
args, but on the wire it is variables. There
is also a format option (A4 and friends) which
takes priority over size; the SDK does not send it.
A successful render returns 201, not 200, with the
file as the response body. If you are checking res.ok you
are fine. If you are checking status === 200 you will
treat every success as a failure.
Retries are already handled
The SDK makes up to five attempts, and only for failures that are worth
retrying: transport errors, 5xx, 408 and
429. A 400 or a bad key is returned to you
immediately rather than retried. The backoff sleeps add up to fourteen
seconds (2 + 3 + 4 + 5).
Two things follow from that:
- Do not wrap these calls in your own retry loop — you will multiply the attempts.
- A call that ultimately fails can take upwards of fifteen seconds before it throws. Set your own timeouts with that in mind, especially inside a request handler.
If you call the REST endpoint directly, none of this applies and retries are yours to implement.
When you should not use this
Worth saying plainly, because it saves everyone an evaluation:
- A few documents a day. A headless browser on a cron job is genuinely fine at that volume. Come back when the batch gets big enough to page someone.
- Air-gapped or offline rendering. This is a cloud API. There is no self-hosted build.
- Long typeset documents. Hundred-page reports with cross-references and running headers are a typesetting problem, and a rendering API is the wrong shape for it.
- You need a document editor. This renders a template you already have; it is not an authoring tool for your end users.