# Automate PDF reports from your data
PDF report automation: query your data, build HTML with SVG or Chart.js charts, add page numbers, render to PDF on a schedule and email it.
Weekly KPI summaries, monthly client reports and end-of-day sales digests are usually the same layout with new numbers. Instead of copying charts into a document every week, build the report as HTML from your data. A scheduled job then turns it into a PDF.
**Quick answer.** Build the report as HTML, then POST it to `https://html-pdf.com/v1/pdf` from a scheduled job and save or email the result.
```bash
curl https://html-pdf.com/v1/pdf -H "Authorization: Bearer $HTML_PDF_KEY" \
-d '{"html":"
Weekly sales report
Revenue: $4,210
"}' -o weekly-report.pdf
```
## The pipeline
These are the five steps every automated report goes through.
1. **Query** your database, warehouse or analytics API.
2. **Build HTML**: tables for numbers, SVG or Chart.js for charts.
3. **Render** with `POST https://html-pdf.com/v1/pdf`.
4. **Deliver**: email the PDF, upload it to storage, or post the link to a chat channel.
5. **Schedule** the whole thing with cron, GitHub Actions or a workflow tool such as n8n.
The free [report template](https://html-pdf.com/templates/report) gives you a starting layout with a title block, KPI cards and a table.
## Build the HTML from query results (Python)
This script turns a SQL query into a report with an SVG bar chart, a table and page numbers.
```python
import os, html, sqlite3, requests
db = sqlite3.connect("shop.db")
rows = db.execute("""
SELECT date(created_at) AS day, COUNT(*) AS orders, SUM(total) AS revenue
FROM orders WHERE created_at >= date('now', '-7 day')
GROUP BY day ORDER BY day
""").fetchall()
max_rev = max((r[2] for r in rows), default=0) or 1
bars = "".join(
f''
f'{html.escape(r[0][5:])}'
for i, r in enumerate(rows))
table = "".join(f"
',
"max_pages": 20,
}, timeout=60)
r.raise_for_status()
open("weekly-report.pdf", "wb").write(r.content)
```
The doubled braces in the CSS are Python f-string escaping. Server-side SVG is the most predictable option for charts. There is no JavaScript to wait for, and the output is sharp at any zoom.
## Charts with Chart.js
This section shows how to use Chart.js if your team already relies on it. Load it from a CDN, turn animations off, and tell the renderer when the chart is ready with `wait_for_expression`.
```html
```
Send it with `"wait_for_expression": "window.chartReady === true"`. More detail in [Chart.js to PDF](https://html-pdf.com/chartjs-to-pdf).
## Page numbers and page breaks
This section keeps multi-page reports readable. `footer_html` uses Chrome's placeholders (`pageNumber`, `totalPages`) and needs a bottom margin to have room.
CSS `@page` margin boxes such as `@bottom-center { content: counter(page) }` also work in Chromium. Keep tables readable with a repeating `thead` and `break-inside: avoid` on rows and charts.
See [headers, footers and page numbers](https://html-pdf.com/pdf-headers-footers-page-numbers) and [page breaks](https://html-pdf.com/html-to-pdf-page-breaks).
## Schedule it
These examples run the report script automatically every Monday at 07:00.
**cron** on any server:
```
0 7 * * 1 cd /opt/reports && HTML_PDF_KEY=... python3 weekly_report.py
```
**GitHub Actions**:
```yaml
name: weekly-report
on:
schedule:
- cron: "0 7 * * 1"
jobs:
report:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: pip install requests
- run: python weekly_report.py
env:
HTML_PDF_KEY: ${{ secrets.HTML_PDF_KEY }}
- uses: actions/upload-artifact@v4
with: { name: weekly-report, path: weekly-report.pdf }
```
Scheduled workflows run in UTC.
**n8n** uses a Schedule Trigger, a database node, a Code node that builds the HTML, then an HTTP Request node calling the API. See the [n8n guide](https://html-pdf.com/guides/n8n).
## Email the PDF
This section covers getting the report to people. Attach the file with your mail provider's SDK or SMTP.
If you'd rather send a link, request `"response": "url"`. The API returns a download URL that stays valid for 24 hours, which suits a "this week's report" email. For anything that must live longer, upload the binary to your own storage.
## Automate reports with html-pdf.com
This is what you get with the hosted API. html-pdf.com is a Chromium-based HTML and URL to PDF API with page-based pricing. You get 100 free credits, then from $0.005 per page, and purchased credits never expire.
A 4-page weekly report costs 4 credits. Requests can be up to 20 MB and render for up to 30 seconds, and your HTML is not stored.
With the [MCP server](https://html-pdf.com/pdf-mcp-server), an AI agent can produce the report straight from data you paste or query.
> *"Take this CSV of last month's sales by region, build a two-page PDF report with a bar chart per region, a summary table and page numbers in the footer, and give me the link."*
[Get an API key](https://html-pdf.com/login)
## FAQ
### How do I automate PDF reports from a database?
Query your data, build an HTML page with tables and SVG or Chart.js charts, and POST it to `https://html-pdf.com/v1/pdf`. Run the script on a schedule with cron, GitHub Actions or n8n.
### How do I include Chart.js charts in a PDF report?
Turn animations off and set a flag such as `window.chartReady = true` once the chart is drawn. Then send `"wait_for_expression": "window.chartReady === true"` so the renderer waits for it.
### How much does an automated PDF report cost?
1 credit = 1 PDF page, so a 4-page weekly report costs 4 credits. You get 100 free credits once, then packs from $10 for 1,000 pages to $250 for 50,000 pages.
### Can I email a link instead of attaching the PDF?
Yes. Request `"response": "url"` and the API returns a download link that lasts 24 hours. For longer storage, upload the PDF to your own storage.