> ## Documentation Index
> Fetch the complete documentation index at: https://docs.blinkpdf.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Convert AI and LLM Output to PDF with Blink PDF API

> Turn OpenAI and Claude Markdown output into professional PDFs in ~100ms. Pass LLM responses directly to Blink PDF — no reformatting needed.

Large language models like OpenAI's GPT-4 and Anthropic's Claude produce Markdown natively, which means you can pipe their output straight into Blink PDF without any intermediate transformation step. This makes Blink PDF a natural fit for AI-powered document generation: your model writes the content, and you get a polished, shareable PDF in under 100ms.

<Note>
  Building inside an **AI agent** like Claude Code or Codex? Skip the glue code entirely — connect the [Blink PDF MCP server](/mcp/overview) and your agent renders PDFs in plain language with `render_pdf`, plus tools to validate a body, stage images, and list themes and fonts. The patterns below cover the REST-based pipeline.
</Note>

## Why LLM Output Maps Perfectly to Blink PDF

LLMs are trained on Markdown-heavy corpora and default to it whenever they generate structured content — reports, summaries, analyses, and proposals all arrive pre-formatted with headings, bullet lists, bold text, and tables. Blink PDF's `/v1/render` endpoint accepts that Markdown directly as a JSON string, so the integration is essentially zero-glue:

1. Prompt your model to produce a Markdown document.
2. Take `response.choices[0].message.content` (or the Claude equivalent).
3. POST it to `/v1/render`.
4. Receive a ready-to-use PDF binary.

<Note>
  Your **Markdown input is never persisted** — it's processed in memory and discarded when the response closes. Generated PDFs and any staged assets are purged within 24 hours. This makes the pipeline safe for sensitive AI outputs such as legal summaries, financial analyses, and medical drafts. See [Zero Retention](/concepts/zero-retention).
</Note>

## Basic Pattern

```text theme={null}
LLM API → Markdown string → POST /v1/render → PDF binary → save / send
```

Every example below follows this pattern. Swap in any LLM provider; only the first step changes.

## Code Examples

<CodeGroup>
  ```python Python (OpenAI) theme={null}
  import base64
  import json

  import openai
  import requests

  client = openai.OpenAI(api_key="sk-...")

  # Step 1: Ask the model to generate a Markdown report
  completion = client.chat.completions.create(
      model="gpt-4o",
      messages=[
          {
              "role": "system",
              "content": (
                  "You are a professional analyst. "
                  "Respond with a well-structured Markdown report only — "
                  "no commentary outside the document."
              ),
          },
          {
              "role": "user",
              "content": "Write a Q3 2024 performance summary for an e-commerce business.",
          },
      ],
  )

  markdown_content = completion.choices[0].message.content

  # Step 2: Render the Markdown to PDF
  response = requests.post(
      "https://api.blinkpdf.io/v1/render",
      headers={
          "x-api-key": "bp_xxxxxxxxxxxxxxxxxxxx",
          "Accept": "application/pdf",
          "Content-Type": "application/json",
      },
      json={
          "markdown": markdown_content,
          "metadata": {"title": "Q3 2024 Performance Summary"},
      },
  )

  response.raise_for_status()

  # Step 3: Save the PDF
  with open("q3_summary.pdf", "wb") as f:
      f.write(response.content)

  request_id = response.headers.get("X-Request-Id")
  status = response.headers.get("X-Render-Status", "ok")
  rendered_ok = response.headers.get("X-Render-Rendered-As-Requested", "true")

  diagnostics = []
  raw = response.headers.get("X-Render-Diagnostics")
  if raw:
      padded = raw + "=" * (-len(raw) % 4)
      diagnostics = json.loads(base64.urlsafe_b64decode(padded))

  print(
      f"PDF saved — request ID: {request_id} "
      f"(status: {status}, rendered as requested: {rendered_ok}, "
      f"{len(diagnostics)} diagnostic(s))"
  )
  ```

  ```python Python (Claude / Anthropic) theme={null}
  import anthropic
  import requests

  client = anthropic.Anthropic(api_key="sk-ant-...")

  # Step 1: Generate Markdown with Claude
  message = client.messages.create(
      model="claude-opus-4-5",
      max_tokens=2048,
      messages=[
          {
              "role": "user",
              "content": (
                  "Write a Markdown competitive analysis report "
                  "for a SaaS project management tool. "
                  "Use headings, bullet points, and a comparison table."
              ),
          }
      ],
  )

  markdown_content = message.content[0].text

  # Step 2: Render to PDF
  response = requests.post(
      "https://api.blinkpdf.io/v1/render",
      headers={
          "x-api-key": "bp_xxxxxxxxxxxxxxxxxxxx",
          "Accept": "application/pdf",
          "Content-Type": "application/json",
      },
      json={
          "markdown": markdown_content,
          "metadata": {"title": "Competitive Analysis Report"},
      },
  )

  response.raise_for_status()

  # Step 3: Save
  with open("competitive_analysis.pdf", "wb") as f:
      f.write(response.content)

  print(f"Request ID: {response.headers['X-Request-Id']}")
  ```

  ```javascript Node.js (OpenAI SDK + fetch) theme={null}
  import OpenAI from "openai";
  import { writeFileSync } from "fs";

  const openai = new OpenAI({ apiKey: "sk-..." });

  async function generateReportPDF() {
    // Step 1: Generate Markdown from OpenAI
    const completion = await openai.chat.completions.create({
      model: "gpt-4o",
      messages: [
        {
          role: "system",
          content:
            "You are a business analyst. Respond with a structured Markdown report only.",
        },
        {
          role: "user",
          content: "Write a monthly executive summary for a SaaS company.",
        },
      ],
    });

    const markdownContent = completion.choices[0].message.content;

    // Step 2: Send to Blink PDF
    const response = await fetch("https://api.blinkpdf.io/v1/render", {
      method: "POST",
      headers: {
        "x-api-key": "bp_xxxxxxxxxxxxxxxxxxxx",
        Accept: "application/pdf",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        markdown: markdownContent,
        metadata: { title: "Monthly Executive Summary" },
      }),
    });

    if (!response.ok) {
      throw new Error(`Blink PDF error: ${response.status} ${response.statusText}`);
    }

    // Step 3: Save the PDF
    const buffer = Buffer.from(await response.arrayBuffer());
    writeFileSync("executive_summary.pdf", buffer);

    console.log(`PDF saved — request ID: ${response.headers.get("X-Request-Id")}`);
  }

  generateReportPDF();
  ```
</CodeGroup>

## Agentic Workflows

When you're building autonomous agents that produce multiple documents across a workflow run, a few patterns help you stay efficient and within your [rate limits](/plans/rate-limits).

### Async Batch Generation

If your agent produces several reports in one run, fire the render requests concurrently rather than sequentially. At Pro plan (120 req/min) you can sustain roughly two renders per second without hitting limits. See the [Batch Processing guide](/guides/batch-processing) for a full async example.

### Prompt Engineering for Clean PDFs

Guide the model to produce render-ready Markdown by adding explicit instructions in your system prompt:

```text theme={null}
Respond with a complete Markdown document only.
- Start with a single H1 title.
- Use H2 and H3 for sections.
- Use tables for structured comparisons.
- Do not include code fences, commentary, or apologies outside the document.
```

This prevents preamble text like "Sure, here's your report:" from appearing in the rendered PDF.

### Streaming + Buffering

If you use OpenAI's streaming API to display content progressively in a UI, buffer the full completion before sending it to `/v1/render`. Blink PDF requires the complete Markdown document in a single request.

<Tip>
  Store `X-Request-Id`, `X-Render-Status`, and `X-Render-Rendered-As-Requested` alongside each document record. Decode `X-Render-Diagnostics` when you need the full list of renderer warnings and errors — see the [API overview](/api-reference/overview#render-status).
</Tip>

## Connecting to Notion, Obsidian, and Tiptap

Blink PDF integrates well with editor-based AI workflows:

* **Notion AI** — Export Notion page content as Markdown via the Notion API, then render with Blink PDF to produce a shareable PDF snapshot.
* **Obsidian** — Use the Obsidian Local REST API plugin or a community plugin to pipe vault notes to `/v1/render` on demand.
* **Tiptap** — Convert Tiptap's JSON document model to Markdown using `@tiptap/extension-markdown`, then pass the string directly to Blink PDF.

## Plan Considerations

| Plan               | Rate Limit | Best For                            |
| ------------------ | ---------- | ----------------------------------- |
| Free               | 10/min     | Prototyping LLM-to-PDF pipelines    |
| Pro (\$9/mo)       | 120/min    | Production AI apps, daily reporting |
| Business (\$79/mo) | 600/min    | High-frequency agentic workflows    |
| Enterprise         | Custom     | Enterprise AI document platforms    |

<Info>
  On every plan, your Markdown input is never persisted; generated PDFs and staged assets are purged within 24 hours. See [Pricing](/plans/pricing) for render-unit allowances.
</Info>
