Documentation Index
Fetch the complete documentation index at: https://markdown2pdf.ai/llms.txt
Use this file to discover all available pages before exploring further.
Here’s a few examples of how to use markdown2pdf.ai in your code.
Python
Typescript
MCP
X402 (Python)
pip install markdown2pdf-python
from markdown2pdf import MarkdownPDF
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)
path = client.convert(markdown="# Hello from Python", title="My document title", download_path="output.pdf")
print("Saved PDF to:", path)
npm install @serendipityai/markdown2pdf-typescript
import { convertMarkdownToPdf } from "@serendipityai/markdown2pdf-typescript";
import type { OfferDetails } from "@serendipityai/markdown2pdf-typescript";
async function pay(offer: OfferDetails) {
console.log("⚡ Lightning payment required");
console.log(`Amount: ${offer.amount} ${offer.currency}`);
console.log(`Description: ${offer.description}`);
console.log(`Invoice: ${offer.payment_request}`);
await new Promise<void>(resolve => { process.stdin.once("data", () => { resolve(); }); });
}
async function main() {
const result = await convertMarkdownToPdf("# Hello from Typescript", {
title: "My document title",
downloadPath: "output.pdf",
onPaymentRequest: pay
});
console.log("Saved PDF to:", result);
}
main().catch(console.error);
You can drop the below configuration in to your Claude MCP config to add PDF conversion to your chat workflow."mcpServers": {
"markdown2pdf": {
"command":"npx",
"args": ["@serendipityai/markdown2pdf-mcp"],
"cwd": "~"
}
}
pip install "x402[httpx]" solders
import os, asyncio
from solders.keypair import Keypair
from x402 import x402Client, prefer_network
from x402.http.clients.httpx import x402HttpxClient
from x402.mechanisms.svm import KeypairSigner
from x402.mechanisms.svm.exact import ExactSvmScheme
async def main():
keypair = Keypair.from_base58_string(os.environ["SOLANA_SIGNER_KEY"])
signer = KeypairSigner(keypair)
NETWORK = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"
x402 = x402Client()
x402.register(NETWORK, ExactSvmScheme(signer=signer))
x402.register_policy(prefer_network(NETWORK))
async with x402HttpxClient(x402, timeout=120.0) as client:
resp = await client.post(
"https://api.markdown2pdf.ai/markdown",
json={
"data": {"text_body": "# Hello from X402"},
"options": {"document_name": "hello.pdf"},
},
)
resp.raise_for_status()
print("Paid tx proof:", resp.headers.get("payment-response"))
print("Poll:", resp.json()["path"])
asyncio.run(main())
The x402HttpxClient handles the 402 → sign → retry loop for you. See the
X402 page for details and manual-flow variants.
You’ll see that, in general, you pass your markdown content, a title and a download path to the convert function and it will handle the markdown conversion for you. A mandatory function must be provided which is used to handle the payment using a mechanism of your choice — either Lightning via L402 or USDC on Solana via X402. This could be a manual payment (copy-and-paste the Lightning invoice into a wallet of your choice, or sign an X402 X-PAYMENT header with a Solana wallet), but more likely will be handled programmatically via a Lightning wallet or a Solana signer.