Query the "Generate PDF" tool (async)

Invoke the "Generate PDF" directly as a background task.

Query Params

The ID of the Chat to use. If not provided, a new Chat will be created.

array | null

If creating a new chat, add these tags to it. This is ignored if the chat already exists.

Body Params
string
required

Python code to run in a sandboxed environment that builds a PDF.

The code runs in a restricted Python sandbox. You MUST follow these rules:

  • You CANNOT import third-party packages. All PDF functionality is through
    the build_pdf function available in the sandbox.
  • You CANNOT define classes. Use dicts instead.
  • You CAN only import: sys, os, typing, asyncio, re, datetime, json, math.
  • Wall-clock and OS calls are BLOCKED: do NOT call datetime.now,
    datetime.today, date.today, time.time, time.monotonic,
    os.getenv, os.urandom, uuid.uuid4, or any similar non-deterministic
    OS function. If you need a timestamp, call await report_generated_at()
    or await report_today() (both documented below).
  • The last expression in your code is the return value.

Available functions:

async def build_pdf(sections, title='Report', style=None) -> str:
    """Render sections into a PDF. Returns base64 PDF bytes.
    style dict keys: header_color, font_family,
    title_font_size, heading1_font_size, heading2_font_size,
    body_font_size, table_font_size, code_font_size"""

async def fetch_chart(asset_id: str) -> str:
    """Fetch a chart PNG as base64 string. Use with image section."""

async def fetch_table_data(asset_id: str, max_rows: int = 50) -> dict:
    """Fetch CSV as {"columns": [...], "rows": [[...]], "total_rows": int}."""

async def list_available_assets() -> list[dict]:
    """List all assets in the chat.
    Returns [{"asset_id": ..., "mime_type": ...}].
    Use to discover charts (image/png) and tables (text/csv)."""

async def get_chat_history() -> str:
    """Get the conversation as plain text (User/Assistant turns).
    Call this first to understand what was discussed."""

async def report_generated_at() -> str:
    """Human-readable timestamp for this report run, e.g.
    'May 04, 2026 at 11:28 UTC'. Use this instead of datetime.now."""

async def report_today() -> str:
    """Today's date in ISO format, e.g. '2026-05-04'.
    Use this instead of datetime.today or date.today."""

Section type reference:

  • {"type": "title", "text": "..."}
  • {"type": "heading", "text": "...", "level": 1 or 2}
  • {"type": "paragraph", "text": "..."}
  • {"type": "code", "text": "..."} (monospace)
  • {"type": "table", "headers": [...], "rows": [[...]]}
  • {"type": "data_table", "headers": [...], "rows": [[...]], "title": "..."}
  • {"type": "image", "data_base64": "...", "title": "..."}
  • {"type": "list", "items": ["First point", "Second point", ...]}
  • {"type": "spacer", "height": 0.3}
  • {"type": "page_break"}

Example:

  • Use a specific noun-phrase title derived from the subject, NOT a generic
    label like 'Chat Summary' or 'Report'.
  • Use short human-readable titles for images and data_tables. NEVER pass
    the raw asset_id as a title.
  • Only fetch and embed assets relevant to the chosen report scope.
sections = [
    {"type": "title", "text": "Q4 2023 Shipping Performance"},
    {"type": "heading", "text": "Overview", "level": 1},
    {"type": "paragraph", "text": (
        "Shipping held up through Q4 2023: 645 orders moved across "
        "weeks 39-52, with roughly 45% early, 26% on time, and 29% "
        "late."
    )},
]
# Embed only assets in scope. Use human-readable titles, not asset IDs.
for asset in await list_available_assets():
    if asset['asset_id'] not in scope_asset_ids:
        continue
    if asset["mime_type"] == "image/png":
        b64 = await fetch_chart(asset["asset_id"])
        if b64:
            sections.append({"type": "image", "data_base64": b64,
                "title": "Weekly Orders by Shipping Status"})
    elif asset["mime_type"] == "text/csv":
        td = await fetch_table_data(asset["asset_id"])
        if td["columns"]:
            sections.append({"type": "data_table",
                "headers": ["Week", "Early", "On Time", "Late"],
                "rows": td["rows"],
                "title": "Weekly Shipping Detail"})
result = await build_pdf(sections, "Q4 2023 Shipping Performance")
result
string
required

A short noun phrase describing the PDF subject. Used as the in-PDF title and the downloaded filename. 3-8 words, plain letters/numbers/spaces only (no colons, em dashes, or slashes -- they become underscores in the filename). Examples: 'Q4 2023 Shipping Performance', '2023 Monthly Sales by Region'. Do not use the user's question or generic titles like 'Chat Summary'.

Responses

Language
Credentials
URL
LoadingLoading…
Response
Choose an example:
application/json