Our Python SDK makes it easy to use markdown2pdf.ai in your agentic workflows. Whilst using our REST APIs is straightforward, there are some complexities to handle around polling for payment completion and document generation that the SDK avoids you needing to worry about.
First up, you’ll need to install the SDK:
Copy
pip install markdown2pdf-python
With that done, you can try some sample code:
Copy
from markdown2pdf import MarkdownPDFdef pay(offer): print("⚡ Lightning payment required") print(f"Amount: {offer['amount']} {offer['currency']}") print(f"Description: {offer['description']}") print(f"Invoice: {offer['payment_request']}") input("Press Enter once paid...")client = MarkdownPDF(on_payment_request=pay)path = client.convert(markdown="# Insert your own markdown content here", title="My document title", download_path="output.pdf")print("Saved PDF to:", path)
This code will convert the markdown content you provide into a PDF, prompting you to pay via Lightning Network if necessary. The on_payment_request function is called when payment is required, allowing you to handle the payment process in your application. There are several ways of handling payments automatically, such as fewsats.com or albyhub or using a Lightning wallet that supports automatic payments. In the example above, we simply print the payment details and wait for you to confirm payment manually. You can simply copy and paste the lightning invoice into your lightning wallet to pay.
This function is called when a payment is required. It receives an offer object containing details about the payment, such as amount, currency, description, and the Lightning invoice. You can implement your own logic to handle payments here. This parameter is required because the service uses the L402 protocol, which requires a payment to be made before generating the PDF.
Copy
def pay(offer): print("⚡ Lightning payment required") print(f"Amount: {offer['amount']} {offer['currency']}") print(f"Description: {offer['description']}") print(f"Invoice: {offer['payment_request']}") input("Press Enter once paid...")client = MarkdownPDF(on_payment_request=pay)
This parameter enables you to override the default API URL. This is typically used in development or testing environments, but for normal usage you won’t need to touch it and it can be set to None or omitted.
Converts the provided markdown content into a PDF document. This method handles the payment process automatically if required, and saves a PDF to the specified path or returns it as bytes.
A string containing the markdown content you want to convert to PDF.
A note on markdown hashing
markdown2pdf.ai uses a hashing mechanism to ensure that you won’t get charge twice for creating the same PDF. Subsequent requests to convert the same markdown content will return the previously generated PDF without requiring a new payment.
Typically your markdown will come from the output of an LLM or AI agent. If you want to load some from a file, you can do it like this:
Copy
from markdown2pdf import MarkdownPDFfrom pathlib import Pathdef pay(offer): print("⚡ Lightning payment required") print(f"Amount: {offer['amount']} {offer['currency']}") print(f"Description: {offer['description']}") print(f"Invoice: {offer['payment_request']}") input("Press Enter once paid...")client = MarkdownPDF(api_url="https://qa.api.markdown2pdf.ai", on_payment_request=pay)markdown = Path("examples/md/Song of the silent stars.md").read_text(encoding="utf-8")url = client.convert(markdown=markdown, title="Song of the silent stars", date="5th June 2025" ) print("PDF URL:", url)
Whether or not to return the PDF as bytes instead of saving it to a file. If set to True, the method will return the PDF content as a byte string. If set to False, it will save the PDF to the specified download_path or return the path if no path is provided.
For example:
Copy
pdf_bytes = client.convert(markdown="# Memory use case", return_bytes=True) print(f"PDF size in memory: {len(pdf_bytes)} bytes")
If you want to automate payments, you can use a service like fewsats.com or Albyhub. These services allow you to automatically pay Lightning invoices, completely headlessly.
Copy
from markdown2pdf import MarkdownPDFfrom dotenv import load_dotenvfrom pyalby import Account, Invoice, Paymentload_dotenv()# In your .env file, ensure you have set the following. You can learn more about alby at https://albyhub.com.# BASE_URL = https://api.getalby.com# ALBY_ACCESS_TOKEN = <your_alby_access_token># LOG_LEVEL = INFdef pay(offer): print("Paying using Alby:") payment = Payment() pay = payment.bolt11_payment(offer["payment_request"]) print(f"Payment made: {pay}")client = MarkdownPDF(on_payment_request=pay)path = client.convert(markdown="# Save this one using Alby", download_path="output.pdf") # Replace with your own unique markdown content to ensure you trigger L402.print("Saved PDF to:", path)
Copy
from markdown2pdf import MarkdownPDFfrom dotenv import load_dotenvfrom pyalby import Account, Invoice, Paymentload_dotenv()# In your .env file, ensure you have set the following. You can learn more about alby at https://albyhub.com.# BASE_URL = https://api.getalby.com# ALBY_ACCESS_TOKEN = <your_alby_access_token># LOG_LEVEL = INFdef pay(offer): print("Paying using Alby:") payment = Payment() pay = payment.bolt11_payment(offer["payment_request"]) print(f"Payment made: {pay}")client = MarkdownPDF(on_payment_request=pay)path = client.convert(markdown="# Save this one using Alby", download_path="output.pdf") # Replace with your own unique markdown content to ensure you trigger L402.print("Saved PDF to:", path)
Copy
from markdown2pdf import MarkdownPDFimport requestsLN_BITS_URL = "https://demo.lnbits.com/api/v1/payments"ADMIN_KEY = "<your_lnbits_admin_key>" # Replace with your LNbits admin key, see https://lnbits.comdef pay(offer): print("Paying using lnbits:") headers = {"X-Api-Key": ADMIN_KEY, "Content-Type": "application/json"} data = { "out": True, "bolt11": offer["payment_request"], } res = requests.post(LN_BITS_URL, json=data, headers=headers) res.raise_for_status() print("Payment status:", res)client = MarkdownPDF(on_payment_request=pay)path = client.convert(markdown="# Save this one using lnbits", download_path="output.pdf") # Replace with your own unique markdown content to ensure you trigger L402.print("Saved PDF to:", path)
Copy
from markdown2pdf import MarkdownPDFfrom dotenv import load_dotenvfrom fewsats.core import *load_dotenv()fs = Fewsats()# In your .env file, ensure you have set the following. You can learn more about fewsats at https://fewsats.com.# FEWSATS_API_KEY = <your_fewsats_api_key>def pay(offer): print("Paying using Fewsats:") r = fs.pay_lightning(invoice=offer["payment_request"], amount=offer["amount"], currency=offer["currency"], description=offer["description"]) print(f"Payment made: {r}")client = MarkdownPDF(on_payment_request=pay)path = client.convert(markdown="# Save this one using Fewsats", download_path="output.pdf") # Replace with your own unique markdown content to ensure you trigger L402.print("Saved PDF to:", path)