Python SDK
The official Python SDK is typed, uses requests, and is intended for server-side Python applications. It supports PDFBolt's Direct, Sync, Async, Usage, and webhook signature workflows.
If you prefer calling the REST API directly with Python, see the Python API quick start. For the complete API parameter reference, see Conversion Parameters and the OpenAPI Reference.
Installation
pip install pdfbolt
Requires Python 3.11 or newer.
Quick Start
This example converts https://example.com to a PDF, saves it as example.pdf, and prints the SDK version and output size.
import os
from pdfbolt import PDFBolt, VERSION
pdfbolt = PDFBolt(api_key=os.environ["PDFBOLT_API_KEY"])
pdf = pdfbolt.direct.from_url(
url="https://example.com",
print_background=True,
)
pdf.save("example.pdf")
print(f"Using PDFBolt SDK {VERSION}")
print(f"Saved {pdf.size} bytes")
Python SDK options use snake_case and are mapped to PDFBolt REST API fields:
print_background->printBackgroundcustom_s3_presigned_url->customS3PresignedUrlextra_http_headers->extraHTTPHeaders
template_data keys are sent unchanged, so they continue to match your template variables exactly.
Convert a URL to PDF
Use from_url() when you want PDFBolt to load an HTTPS page and render it as a PDF.
pdf = pdfbolt.direct.from_url(
url="https://example.com",
format="A4",
print_background=True,
)
pdf.save("url.pdf")
Convert HTML to PDF
Use from_html() when you have raw HTML. The SDK automatically encodes it to Base64 for the API.
pdf = pdfbolt.direct.from_html(
html="<h1>Hello from PDFBolt</h1>",
format="A4",
)
pdf.save("hello.pdf")
If you already have a Base64-encoded HTML string, use convert() directly. It returns the same DirectConversionResult as from_html().
pdf = pdfbolt.direct.convert({
"html": "PGgxPkhlbGxvPC9oMT4="
})
pdf.save("hello.pdf")
Header and footer templates work the same way: from_url(), from_html(), and from_template() accept raw HTML templates and automatically encode them to Base64, while convert() expects Base64-encoded template values.
This rule applies to all low-level convert() methods: direct.convert(), sync.convert(), and async_conversions.convert() send HTML and header/footer template values as provided.
See the headerTemplate and footerTemplate parameter docs for supported placeholders and examples.
pdf = pdfbolt.direct.from_html(
html="<!doctype html><html><body><h1>Invoice</h1></body></html>",
display_header_footer=True,
header_template='<div style="font-size:9px;width:100%;text-align:center;">Invoice</div>',
footer_template='<div style="font-size:9px;width:100%;text-align:center;">Page <span class="pageNumber"></span> of <span class="totalPages"></span></div>',
margin={
"top": "20mm",
"bottom": "20mm",
},
)
pdf.save("invoice.pdf")
Convert a Template to PDF
Use from_template() with a published PDFBolt template ID and the JSON data for that template.
pdf = pdfbolt.direct.from_template(
template_id="00000000-0000-0000-0000-000000000000",
template_data={
"invoiceNumber": "INV-1001",
"customerName": "Acme Inc.",
"total": "$250.00",
},
)
pdf.save("template.pdf")
template_data is sent as provided. The SDK does not rename keys inside your template data object.
Direct Results
Use pdfbolt.direct when you want the generated PDF returned in the HTTP response. Direct conversions return a DirectConversionResult.
DirectConversionResult.buffer always contains PDF bytes. When you pass is_encoded=True, PDFBolt returns Base64 text and the SDK exposes it as DirectConversionResult.base64. DirectConversionResult.buffer still contains decoded PDF bytes, so save() works the same way.
pdf = pdfbolt.direct.from_url(
url="https://example.com",
filename="example.pdf",
)
pdf.save("example.pdf")
print(pdf.buffer) # bytes with PDF content
print(pdf.base64) # string only when is_encoded=True, otherwise None
print(pdf.size)
print(pdf.content_type)
print(pdf.content_disposition)
print(pdf.filename)
print(pdf.conversion_cost)
print(pdf.rate_limit.minute.remaining)
print(pdf.headers.get("x-pdfbolt-conversion-cost"))
Direct, Sync, Async job, and Usage results expose parsed rate-limit values through rate_limit. Rate-limit fields can be None when a response does not include the matching header. Direct results also expose raw HTTP headers through pdf.headers.
Get a Temporary URL
Use pdfbolt.sync when you want PDFBolt to generate the document and return a temporary download URL, valid for 24 hours.
result = pdfbolt.sync.from_url(url="https://example.com")
print(result.request_id)
print(result.status)
print(result.document_url)
print(result.expires_at)
print(result.duration)
print(result.document_size_mb)
print(result.rate_limit.minute.remaining)
print(result.conversion_cost)
For custom S3 uploads, pass a valid presigned URL. PDFBolt uploads the generated PDF to your S3-compatible bucket, so document_url and expires_at are None. Custom S3 uploads are available on paid plans.
result = pdfbolt.sync.from_html(
html="<h1>Invoice</h1>",
custom_s3_presigned_url=os.environ["PDFBOLT_CUSTOM_S3_PRESIGNED_URL"],
)
print(result.is_custom_s3_bucket) # True
print(result.document_url) # None
Presigned URLs are usually time-limited and often single-use. Generate a new one for each conversion. See Uploading to Your S3 Bucket for setup details.
Run an Async Conversion
Use pdfbolt.async_conversions when the conversion should run in the background. The request returns an accepted job with a request_id immediately, and PDFBolt sends the final success or failure payload to your HTTPS webhook later.
job = pdfbolt.async_conversions.from_url(
url="https://example.com",
webhook="https://your-app.com/webhooks/pdfbolt",
retry_delays=[5, 15, 60],
)
print(job.request_id)
print(job.rate_limit.minute.remaining)
retryDelays are in minutes and retry the conversion attempt itself, not webhook delivery.
For async custom S3 uploads, pass a valid custom_s3_presigned_url in the async request. After a successful upload, the final webhook has is_custom_s3_bucket=True, document_url=None, and expires_at=None.
Verify Webhook Signatures
Use the exact raw request body received from your framework. Do not parse and re-serialize JSON before verification. Supported raw body types are str, bytes, bytearray, and memoryview.
For Flask, use request.get_data() as the raw body. For FastAPI or Starlette, use await request.body().
The secret value is your PDFBolt webhook signature key, not your API key. You can find the webhook signature key on the API Keys page in the Dashboard.
import os
from pdfbolt import webhooks
event = webhooks.verify_and_parse(
raw_body=raw_body,
signature=request.headers.get("x-pdfbolt-signature"),
secret=os.environ["PDFBOLT_WEBHOOK_SECRET"],
)
print(event.request_id)
print(event.status)
print(event.error_code)
print(event.document_url)
verify_and_parse() verifies the HMAC signature first and parses JSON only after the signature is valid. If you only need a boolean result, use webhooks.verify_signature().
The SDK exposes webhook helpers through both PDFBolt.webhooks and the top-level webhooks export. Use whichever import style fits your codebase.
Error Handling
The PDFBolt API returns one common error response shape. The SDK represents API error responses with one class: PDFBoltAPIError. Check status_code for HTTP-level handling and error_code for PDFBolt-specific causes.
from pdfbolt import (
PDFBoltAPIError,
PDFBoltError,
PDFBoltNetworkError,
PDFBoltValidationError,
)
try:
pdfbolt.direct.from_url(url="https://example.com")
except PDFBoltValidationError as error:
print(error)
except PDFBoltAPIError as error:
print(error.status_code)
print(error.timestamp)
print(error.error_code)
print(error.error_message)
print(error.rate_limit.minute.limit)
print(error.rate_limit.minute.remaining)
print(error.raw_body)
if error.status_code == 401:
print("Check your API key.")
if error.error_code == "TOO_MANY_REQUESTS":
print(error.rate_limit.minute.remaining)
except PDFBoltNetworkError as error:
print(error)
except PDFBoltError:
raise
PDFBoltError is the base class for all SDK errors. PDFBoltAPIError is thrown when the PDFBolt API returns an HTTP error response.
Exported error classes:
PDFBoltError
PDFBoltAPIError
PDFBoltNetworkError
PDFBoltWebhookSignatureError
PDFBoltValidationError
PDFBoltConfigurationError
See Error Handling for the full API error reference. These SDK-specific classes are worth calling out:
PDFBoltValidationErroris thrown before a request is sent when a high-level helper is called with missing or invalid SDK-side parameters.PDFBoltConfigurationErroris thrown before a request is sent, for example when the API key is missing.PDFBoltNetworkErrormeans the SDK did not receive a usable HTTP response, for example because of a network failure, timeout, or malformed success response.PDFBoltWebhookSignatureErroris thrown byverify_and_parse()when the webhook signature or payload is invalid.
Advanced Client Options
import os
import requests
from pdfbolt import PDFBolt
session = requests.Session()
pdfbolt = PDFBolt(
api_key=os.environ["PDFBOLT_API_KEY"],
base_url="https://api.pdfbolt.com",
request_timeout=120.0,
session=session,
)
The SDK does not automatically retry failed requests. One SDK method call sends at most one HTTP request. For async conversion retries handled by PDFBolt, use the retry_delays conversion parameter.
request_timeout is the SDK HTTP timeout in seconds. The default is 120.0. The conversion timeout option is different: it is sent to the PDFBolt API in milliseconds and controls the browser render timeout for the PDF conversion, for example timeout=30000.
The SDK sends User-Agent: pdfbolt-python/<version> on requests to the PDFBolt API. This helps identify SDK traffic for support and debugging. To set headers for the page being rendered by Chromium, use the conversion extra_http_headers parameter.
Common conversion options such as format, margin, print_background, content_disposition, filename, and compression use Pythonic snake_case names and are mapped to the REST API request fields. See Conversion Parameters for the full parameter reference.
Usage
Use pdfbolt.usage.get() to read the current account plan, remaining conversion credits, and rate-limit metadata.
usage = pdfbolt.usage.get()
print(usage.plan)
print(usage.recurring)
print(usage.one_time)
print(usage.rate_limit.day.remaining)
SDK Reference
Main client methods:
pdfbolt.direct.convert(...)
pdfbolt.direct.from_url(...)
pdfbolt.direct.from_html(...)
pdfbolt.direct.from_template(...)
pdfbolt.sync.convert(...)
pdfbolt.sync.from_url(...)
pdfbolt.sync.from_html(...)
pdfbolt.sync.from_template(...)
pdfbolt.async_conversions.convert(...)
pdfbolt.async_conversions.from_url(...)
pdfbolt.async_conversions.from_html(...)
pdfbolt.async_conversions.from_template(...)
pdfbolt.usage.get(...)
Webhook helpers:
PDFBolt.webhooks.verify_signature(...)
PDFBolt.webhooks.verify_and_parse(...)
webhooks.verify_signature(...)
webhooks.verify_and_parse(...)
Common runtime exports:
PDFBolt
DirectConversionResult
VERSION
Webhooks
webhooks
PDFBoltError
PDFBoltAPIError
PDFBoltNetworkError
PDFBoltWebhookSignatureError
PDFBoltValidationError
PDFBoltConfigurationError
Typed exports are available for request dictionaries, conversion options, webhook events, result models, rate-limit metadata, cookies, margins, dimensions, and other PDFBolt API parameter types.