Skip to main content

Bubble.io

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 Bubble.io account - sign up for free, no credit card required.

Use Case 1: Generate PDFs from App Data

Let users generate an invoice PDF from a Bubble invoice record and its related line items via the API Connector.
Button click → API Connector (PolyDoc API) → Display/download PDF

Install the API Connector plugin

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

In the Bubble editor, open Data → Data types and create two types:

  • Invoice with the header fields shown in the table above (invoice_number, invoice_date, invoice_due_date, invoice_subtotal, invoice_tax_rate, invoice_tax_amount, invoice_total, customer_name, customer_email, customer_street, customer_city, customer_country).
  • Invoice line item with quantity, name, description, price, original_price, plus an invoice_number field of type Invoice that links each line item back to its parent invoice.

Then switch to App data and seed one sample Invoice row plus its line items so you have data to render when you test in Step 4.

Next, in the Design tab, open the App Manager and click + New → Web page to create an invoice page. With the page selected, set its Type of content to Invoice in the right-side properties panel - this is what makes Current Page Invoice available to the Step 3 workflow. Finally, in Plugins, install the API Connector plugin (built-in by Bubble) which Step 2 configures.

bubble.io

Configure the PolyDoc API call

Open Plugins → API Connector → PolyDoc - Generate PDF and configure a new call:

  • Name: API Call
  • Use as: Action
  • Data type: File (the API returns a binary PDF)
  • Method: POST
  • URL: https://api.polydoc.tech/pdf/convert
  • Headers:
    • Authorization: Bearer YOUR_API_KEY (get from the Dashboard)
    • Content-Type: application/json
    • X-Sandbox: true
  • Body type: JSON. Wrap every dynamic value in <angle_brackets> - Bubble creates a parameter row for each. The line-item array uses a single parameter <items> wrapped in […]; its contents are filled at workflow time (Step 3).

Replace YOUR_TEMPLATE_ID with your own template's short ID - find it in the Dashboard under Templates (e.g. a1b-c2d). See Templates for how the invoice template consumes the templateData fields below.

{
"source": "[template:YOUR_TEMPLATE_ID]",
"templateData": {
"invoice_number": "<invoice_number>",
"invoice_date": "<invoice_date>",
"invoice_due_date": "<invoice_due_date>",
"invoice_subtotal": <invoice_subtotal>,
"invoice_tax_rate": <invoice_tax_rate>,
"invoice_tax_amount": <invoice_tax_amount>,
"invoice_total": <invoice_total>,
"customer_name": "<customer_name>",
"customer_email": "<customer_email>",
"customer_street": "<customer_street>",
"customer_city": "<customer_city>",
"customer_country": "<customer_country>",
"items": [<items>]
}
}

Click Initialize call and provide sample values for every parameter (e.g. INV-2026-001, 2026-01-15, 1320, John Doe, …). For <items> pass a single JSON object like {"quantity":1,"name":"Sample","description":"x","price":100}. Bubble locks the parameter list once the call returns a PDF.

bubble.io

Create a button workflow

Open the invoice page you created in Step 1, drag a Button from the left palette onto the canvas, and set its text to Generate PDF. With the button selected, open the Interaction tab in the right panel and click Add workflow - Bubble creates a Button Generate PDF is clicked event.

Inside that workflow, add the action Plugins → PolyDoc - Generate PDF - API Call and bind every parameter to Current Page Invoice's matching field:

  • Text fields (invoice_number, customer_name, customer_email, customer_street, customer_city, customer_country) = Current Page Invoice's … for each matching field
  • Number fields (invoice_subtotal, invoice_tax_rate, invoice_tax_amount, invoice_total) = Current Page Invoice's … for each matching field
  • Date strings (invoice_date, invoice_due_date) = Current Page Invoice's … :formatted as 2026-01-15 (Bubble dates need an explicit format)
  • items = Current Page Invoice's line items :formatted as text with delimiter , and per-item template:
{
"quantity": <This Invoice line item's quantity>,
"name": <This Invoice line item's name :formatted as json safe>,
"description": <This Invoice line item's description :formatted as json safe>,
"price": <This Invoice line item's price>,
"original_price": <This Invoice line item's original_price>
}
bubble.io

Handle the PDF response

After the API action, chain a second action Element Actions → Open an external website / Download file and set its source to Result of Step 1 (PolyDoc - Generate PDF) - that is the binary PDF returned from the API. Then preview the app, navigate to your invoice page (e.g. /invoice?debug_mode=true&Current+Page+Invoice=… or via a list page that links into it), click Generate PDF, and confirm the file downloads with every field populated - customer address, both dates, subtotal/tax/total, and every line item.

bubble.io

Use Case 2: Automated PDF on New Record

Automatically generate a PDF whenever a new Thing is created in your database, using a backend workflow.
Backend workflow trigger -> API Connector (PolyDoc) -> Save PDF URL

Enable backend workflows

Open Settings → API and tick Enable Workflow API and backend workflows. Bubble prints a Workflow API root URL (e.g. https://<your-app>.bubbleapps.io/version-test/api/1.1/wf) - confirmation that the API surface is on. On a paid plan a Backend workflows entry then appears in the App Manager (page selector); Step 2 defines its first trigger there.

bubble.io

Create a trigger for new Things

Switch to the Backend workflows page (via the page selector enabled in Step 1) and create a Database Trigger Event:

  • Name: On Invoice Create
  • Type: Invoice
  • Trigger condition: This Invoice's Created Date is not empty (Bubble's standard "fires once per new record" idiom - the event fires exactly once when the row is first persisted).

The trigger automatically exposes a This Invoice variable that Step 3's API call reads from.

Add the PolyDoc API Connector action

Inside the On Invoice Create workflow, add the same action defined in Use Case 1 Step 2: Plugins → PolyDoc - Generate PDF - API Call. The call itself is shared between the two use cases - no re-configuration here.

Bind every parameter to This Invoice's matching field, using the same groupings as Use Case 1 Step 3 - only the source variable changes from Current Page Invoice to This Invoice:

  • Text fields (invoice_number, customer_name, customer_email, customer_street, customer_city, customer_country) = This Invoice's …
  • Number fields (invoice_subtotal, invoice_tax_rate, invoice_tax_amount, invoice_total) = This Invoice's …
  • Date strings (invoice_date, invoice_due_date) = This Invoice's … :formatted as 2026-01-15
  • items = This Invoice's line items :formatted as text with delimiter , and the per-item template from Use Case 1 Step 3.

Save the PDF URL to the record

In a backend workflow, the binary PDF returned from the API call cannot be downloaded to a browser - there is no browser tab in the loop. Have PolyDoc upload the PDF directly to your own object store instead, then save the resulting URL on the Invoice record.

Generate a presigned PUT URL for your bucket (S3, GCS, Azure Blob, Cloudflare R2, …) as a first action - use whichever Bubble plugin matches your storage provider. Then extend the API call body defined in Use Case 1 Step 2 with a single extra dynamic value <presigned_url>:

{
"source": "[template:YOUR_TEMPLATE_ID]",
"templateData": { /* …same 13 fields as Use Case 1… */ },
"cloudStorage": {
"presignedUrl": "<presigned_url>"
}
}

Bind <presigned_url> in the workflow to Result of Step 1 (Generate presigned URL)'s url (or whatever the upstream plugin exposes). Finally add a Make changes to a Thing action that stores the file URL (the presigned URL stripped of its query-string signature, i.e. https://<bucket>/<key>) on the Invoice record so the rest of the app can link to the PDF.