Skip to main content

Python Examples

Complete Python examples for using the DocGenLab API with the requests library.

pip install requests

Setup

import requests
import os

API_KEY = os.getenv('DOCGENLAB_API_KEY') # dgl_...
BASE_URL = 'https://api.docgenlab.com/api/v1'

HEADERS = {
'X-API-Key': API_KEY,
'Content-Type': 'application/json',
}

Example 1: Generate a Document

def generate_document(template_id, input_data, output_format='pdf'):
response = requests.post(
f'{BASE_URL}/documents/',
headers=HEADERS,
json={
'template_id': template_id,
'input_json': input_data,
'output_format': output_format, # 'pdf' | 'docx' | 'both'
}
)
response.raise_for_status()
return response.json()


doc = generate_document(
template_id='your-template-uuid',
input_data={
'invoice_number': 'INV-001',
'client_name': 'Acme Corp',
'amount': 1250.00,
'due_date': '2024-02-15',
# Pass lists for {% for %} loops in the template
'line_items': [
{'name': 'Consulting', 'qty': 10, 'price': 100},
{'name': 'Support', 'qty': 5, 'price': 50},
],
}
)

print(f"Document ID : {doc['id']}")
print(f"Status : {doc['status']}")

Example 2: Poll Until Ready and Download

import time

def wait_for_document(document_id, poll_interval=2, timeout=120):
"""Poll document status until ready or failed."""
deadline = time.time() + timeout
while time.time() < deadline:
resp = requests.get(f'{BASE_URL}/documents/{document_id}', headers=HEADERS)
resp.raise_for_status()
doc = resp.json()

if doc['status'] == 'ready':
return doc
if doc['status'] == 'failed':
raise RuntimeError(f"Generation failed: {doc.get('error_message')}")

time.sleep(poll_interval)

raise TimeoutError(f"Document {document_id} not ready after {timeout}s")


def download_document(document_id, output_path, format='pdf'):
resp = requests.get(
f'{BASE_URL}/documents/{document_id}/download',
headers=HEADERS,
params={'format': format},
)
resp.raise_for_status()
with open(output_path, 'wb') as f:
f.write(resp.content)
return output_path


# Full workflow
doc = generate_document('your-template-uuid', {'name': 'John Doe'})
doc = wait_for_document(doc['id'])
download_document(doc['id'], 'output.pdf')
print("Saved output.pdf")

Example 3: Use an Idempotency Key

Prevents duplicate documents if your request is retried:

def generate_idempotent(template_id, input_data, idempotency_key, output_format='pdf'):
response = requests.post(
f'{BASE_URL}/documents/',
headers={**HEADERS, 'X-Idempotency-Key': idempotency_key},
json={
'template_id': template_id,
'input_json': input_data,
'output_format': output_format,
}
)
response.raise_for_status()
return response.json()


doc = generate_idempotent(
template_id='your-template-uuid',
input_data={'invoice_number': 'INV-001', 'client_name': 'Acme Corp'},
idempotency_key='invoice-INV-001-acme', # unique per business event
)

Example 4: With Webhook (Flask handler)

from flask import Flask, request, jsonify
import requests as req

app = Flask(__name__)

@app.route('/webhooks/docgenlab', methods=['POST'])
def webhook_handler():
# Respond immediately — process asynchronously
payload = request.json
app.logger.info(f"Webhook received: {payload['job_id']}{payload['status']}")

if payload['status'] == 'completed':
response = req.get(payload['download_url'])
with open(f"document_{payload['job_id']}.pdf", 'wb') as f:
f.write(response.content)

return jsonify({'status': 'ok'}), 200

if __name__ == '__main__':
app.run(port=5000)

Example 5: List Templates

def list_templates(is_uat=False):
resp = requests.get(
f'{BASE_URL}/templates/',
headers=HEADERS,
params={'is_uat': str(is_uat).lower()},
)
resp.raise_for_status()
return resp.json()


for template in list_templates(is_uat=False):
# token key is 'key', not 'name'
token_keys = [t['key'] for t in template['tokens_json']]
print(f"{template['name']} ({template['id']})")
print(f" Tokens: {', '.join(token_keys)}")

Example 6: Retry with Exponential Backoff

def generate_with_retry(template_id, input_data, max_retries=3):
for attempt in range(max_retries):
try:
return generate_document(template_id, input_data)
except requests.exceptions.HTTPError as e:
if e.response.status_code == 429:
wait = 2 ** attempt # 1s, 2s, 4s
print(f"Rate limited — retrying in {wait}s...")
time.sleep(wait)
else:
raise
raise RuntimeError("Max retries exceeded")

Example 7: Async Generation with asyncio

import asyncio
import aiohttp

async def generate_many(template_id, rows):
"""Generate one document per row concurrently."""
async with aiohttp.ClientSession(headers=HEADERS) as session:
tasks = [
session.post(
f'{BASE_URL}/documents/',
json={'template_id': template_id, 'input_json': row, 'output_format': 'pdf'}
)
for row in rows
]
responses = await asyncio.gather(*tasks)
return [await r.json() for r in responses]


rows = [{'name': f'Customer {i}', 'amount': i * 100} for i in range(1, 11)]
docs = asyncio.run(generate_many('your-template-uuid', rows))
for d in docs:
print(d['id'], d['status'])

Next Steps