Skip to main content

ToolJet

Prerequisites

  • A PolyDoc account and API key - sign up for free, no credit card required. The free plan includes 150 PDF conversions per month.
  • A ToolJet instance - sign up for free on ToolJet Cloud or self-host the open-source edition.

Use Case 1: Generate PDFs from App Data

Let users generate an invoice PDF from a ToolJet table row and its related line items via a workspace-level REST API datasource.
Button click → REST query (PolyDoc) → Download PDF

Add a REST API datasource for PolyDoc

Use invoices (one row per invoice) and invoice_items (line rows linked by invoice_number). Examples below - two tabs in Sheets; two tables or linked records elsewhere.

invoice_numberinvoice_dateinvoice_due_dateinvoice_subtotalinvoice_tax_rateinvoice_tax_amountinvoice_totalcustomer_namecustomer_emailcustomer_streetcustomer_citycustomer_country
INV-2026-0012026-01-152026-02-1412000.11201320John Doejohn.doe@example.com456 Customer AvenueBeautiful CityUK
invoice_numberquantitynamedescriptionpriceoriginal_price
INV-2026-0011Web Design ServicesCustom website design and development for company homepage800
INV-2026-0011Logo DesignProfessional logo design with 3 revision rounds300
INV-2026-0011SEO OptimizationSearch engine optimization for 10 target keywords100150

Load the two tables above into ToolJet - either as ToolJet Database tables or via a PostgreSQL / MySQL datasource. You need an invoices header table and an invoice_items table that links back to invoices via invoice_number. Seed one sample invoice row with three line items so you have data to render when you test in Step 4.

Then open the workspace settings (gear icon in the bottom-left) → Data sources + Add new data sourceREST API and configure a workspace-level datasource that Step 2 reads from:

  • Name: PolyDoc
  • Base URL: https://api.polydoc.tech
  • Headers → Add three rows: Authorization = Bearer YOUR_API_KEY (get one from the Dashboard), Content-Type = application/json, and X-Sandbox = true.

Click Save. The datasource now lives at the workspace level - every app in the workspace, including the Use Case 2 Workflow, can reuse it.

app.tooljet.com

Create a query to call PolyDoc

In your app's Queries panel (bottom-left), click + Add → pick the PolyDoc datasource from Step 1. Configure the query:

  • Name: convertInvoiceToPdf
  • Method: POST
  • URL: /pdf/convert
  • Body type: Raw JSON

Paste the template below into the body and replace YOUR_TEMPLATE_ID with your own template's short ID - find it in the Dashboard under Templates (e.g. a1b-c2d). The bindings reference a Table component called table1 on the canvas (added in Step 3) and a sibling query called lineItemsQuery (also added in Step 3). See Templates for how the invoice template consumes the templateData fields.

{
"source": "[template:YOUR_TEMPLATE_ID]",
"templateData": {
"invoice_number": "{{components.table1.selectedRow.invoice_number}}",
"invoice_date": "{{components.table1.selectedRow.invoice_date}}",
"invoice_due_date": "{{components.table1.selectedRow.invoice_due_date}}",
"invoice_subtotal": {{components.table1.selectedRow.invoice_subtotal}},
"invoice_tax_rate": {{components.table1.selectedRow.invoice_tax_rate}},
"invoice_tax_amount": {{components.table1.selectedRow.invoice_tax_amount}},
"invoice_total": {{components.table1.selectedRow.invoice_total}},
"customer_name": "{{components.table1.selectedRow.customer_name}}",
"customer_email": "{{components.table1.selectedRow.customer_email}}",
"customer_street": "{{components.table1.selectedRow.customer_street}}",
"customer_city": "{{components.table1.selectedRow.customer_city}}",
"customer_country": "{{components.table1.selectedRow.customer_country}}",
"items": {{queries.lineItemsQuery.data}}
}
}

Open the query's Advanced tab and toggle Run query on page load? off - the query should only fire from the button click in Step 4, not whenever the app reloads.

app.tooljet.com

Build the UI with a table and button

Step 2 built the query; Step 3 builds the UI that triggers it. Click the + icon at the top-right of the editor to open the Components panel, then drag two components onto the canvas:

  • A Table component bound to your invoices data. Select it on the canvas, then in the right-side Properties panel set Table data to {{queries.invoicesQuery.data}} (or a direct table reference if you're on ToolJet Database).
  • A Button component near the table, with its text set to Generate PDF.

Then add a second query (Queries panel → + Add) - the Step 2 body already interpolates it as queries.lineItemsQuery.data:

  • Name: lineItemsQuery
  • Source: same as your invoices source (REST, PostgreSQL, ToolJet Database, …).
  • Configure it to return rows from invoice_items filtered by invoice_number = {{components.table1.selectedRow.invoice_number}}. On Advanced, set Trigger on data changes from to components.table1.selectedRow so the items refresh whenever the user picks a different invoice row in the table.

Bind the button to run the query and download

Select the Generate PDF button from Step 3 and open the Events section in the right-side panel. Click + New event handler and configure:

  • Event: On click
  • Action: Run query → Query = convertInvoiceToPdf (the query from Step 2)

Add a second event handler on the same button to deliver the binary PDF as a download:

  • Event: On click
  • Action: Download file
  • Data: data:application/pdf;base64,{{queries.convertInvoiceToPdf.data}}
  • File name: invoice-{{components.table1.selectedRow.invoice_number}}.pdf
  • File type: application/pdf

Click Preview in the top bar, pick a row in the table, then click Generate PDF. The PDF should download with every field populated: customer address, both dates, subtotal/tax/total as numbers, and every line item visible - including the strikethrough original_price on items that have one.