Inkspan › Guides › How to generate a PDF from a template in Django
Call the Inkspan /v1/generate/template endpoint from Django to generate a PDF from a template — no headless browser,
font stack, or rendering infrastructure in your deploy. Keep your API key in the environment and POST.
Keep the key in settings loaded from the environment, not in source. Returning HttpResponse with the PDF content type streams it straight to the browser.
# views.py
import requests
from django.conf import settings
from django.http import HttpResponse
def make_pdf(request):
r = requests.post(
'https://api.inkspan.dev/v1/generate/template',
headers={'X-API-Key': settings.INKSPAN_KEY},
json={"template": "<h1>{{ name }}</h1>", "data": {"name": "Ada"}},
)
r.raise_for_status()
return HttpResponse(r.content, content_type='application/pdf')
| Name | Type | Required | Description |
|---|---|---|---|
template | string | yes | A Jinja2 template. Supports {{ variables }}, {% for %} loops, {% if %} conditionals, and filters. |
data | object | yes | JSON object whose top-level keys become template variables. |
filename | string | no | Filename in the response's Content-Disposition. |
Returns a PDF as a binary stream with Content-Type: application/pdf and Content-Disposition: attachment; filename=document.pdf. Write the response body straight to disk — do not parse it as JSON.
For anything slow, hand the call to Celery and email or store the result — a synchronous request ties up a worker for the duration of the render.
{% for i in items %}…{% endfor %}, not {{#each}}.data become variables. Passing {"data": {"invoice": {...}}} means you reference {{ invoice.number }}, not {{ number }}.| Status | Meaning | Fix |
|---|---|---|
401 | Invalid or missing API key | Send your key in the X-API-Key header. |
402 | Monthly quota exceeded | The response reports used/quota. Upgrade at inkspan.dev/#pricing. |
422 | Missing or invalid parameter | Check required fields in the table above — the body names the offending field. |
Failed requests do not count against your quota; only successful ones are metered.
Get a free API key →Same operation in cURL · Python · Node.js · Other frameworks: Next.js · Laravel · Ruby on Rails · PHP · All guides