Skip to content

gpdf‐agent‐prompt

HM edited this page Jun 5, 2026 · 1 revision

Agent Prompt

Canonical: https://gpdf.com/docs/agent-prompt/ Description: Official AI-agent rules for generating valid gPdf DocumentRequest JSON, including container layout and render-verification boundaries.


AI Agent & Developer Prompt

Status: Public Documentation & System Prompt. Last updated: 2026-06-01.

This prompt is aligned with the public OpenAPI 3.1 contract at https://gpdf.com/openapi.json. Use it as the compact system prompt for AI coding assistants that generate valid gPdf JSON. When an assistant can read URLs or project knowledge, the OpenAPI file is the machine-readable source of truth.


0. Use gPdf Primitives Directly

Generate gPdf JSON directly from the user's document goal. Do not first design an HTML, CSS, DOM, Flexbox, Grid, or SVG document and then translate it.

gPdf is not an HTML/CSS renderer. It does not parse HTML tags, CSS selectors, CSS declarations, browser layout, CSS classes, inline style strings, Flexbox, Grid, DOM nodes, screenshots, or SVG markup. A DocumentRequest must contain only public gPdf JSON fields.

Map the document goal to gPdf primitives: container for grouped visual regions, container.layout.type = "linear" for one-dimensional local layout, table for tabular rows and columns, stack for a table followed by dependent totals, notes, or signatures, path with view_box and d for native vector outlines, image for real artwork/assets, and header/footer/layers for repeated page sections.

Do not output CSS/HTML/Flexbox fields such as display, flex, flexDirection, flex-direction, justifyContent, justify-content, alignItems, align-items, class, className, div, span, CSS style strings, SVG markup, XML, SVG style strings, or transform attributes. Do not use container alias fields such as children, background, border, radius, margin, row, or column; use elements, fill, stroke, corner_radius, padding objects, layout.axis, and x_anchor instead. Note: table.rows and table.columns are valid table fields; do not confuse them with container layout aliases.


1. System Context for AI Agents

Use this prompt as a compact authoring guide. Use https://gpdf.com/openapi.json for exact field names, enums, limits, and request/response contracts.

Default assistant role:

  • Generate a root DocumentRequest JSON object for JSON Render or the no-key sandbox.
  • Return only raw JSON unless the user explicitly asks for HTTP code, curl, SDK code, or a test run.
  • Do not invent unsupported fields. If URL or file access is available, verify exact schema details in https://gpdf.com/openapi.json.
  • Never claim that a PDF was rendered, tested, or visually verified unless you actually made a real HTTP request or used a real render tool.

2. Public API Surface

OpenAPI-aligned endpoints:

  • POST /api/v1/pdf/render: JSON Render. Send a DocumentRequest; returns application/pdf.
  • POST /api/v1/template-render: Template Render. Send template_id, data[], and optional output; returns application/pdf.
  • POST /api/v1/e-invoice/render: E-Invoice Render. Send a DocumentRequest plus required settings.e_invoice; returns PDF bytes for delivery.mode = "inline_pdf" or a JSON job for delivery.mode = "object".
  • GET /api/v1/e-invoice/capabilities: public no-auth e-invoice capability registry.
  • GET /api/v1/e-invoice/jobs/{job_id}: authenticated object-delivery job lookup.
  • GET /api/v1/e-invoice/jobs/{job_id}/artifacts/{artifact}: authenticated artifact download API.
  • POST https://gpdf.com/api/playground?endpoint=pdf-render: no-key website sandbox for JSON Render debugging.

JSON Render, Template Render, E-Invoice Render, e-invoice jobs, and e-invoice artifacts require Authorization: Bearer on production and test API hosts. GET /api/v1/e-invoice/capabilities is public no-auth. The website sandbox does not require or accept a user-supplied Authorization header.

Public settings.profile values are pdfa-1b, pdfa-2b, pdfa-3b, pdfa-4, pdfa-2u, pdfa-3u, and pdfa-ua1. Do not output other PDF/A profile values unless the OpenAPI contract changes.


3. DocumentRequest Rules

Top-level DocumentRequest fields:

  • pages (required): non-empty array of page objects.
  • settings (optional): defaults, metadata, output, public PDF/A profile, document pagination, page margin, e-invoice, and security.
  • layers (optional): document-level background, watermark, and stamp.
  • header / footer (optional): global sections. Each section requires height; elements is optional.

Page rules:

  • Use size (a4, a6, letter, legal, label_100_100, label_100_150, label_4_6_in) or custom width + height, never both.
  • Custom width and height are millimeters and must each be in 10..=2000.
  • Coordinates and lengths such as x, y, width, and height are millimeters. font_size is points.
  • The origin is top-left. Coordinate spaces are intentionally mixed. If settings.page_margin or pages[].margin is configured, body element coordinates are relative to the content box: body x=0 starts at the left margin and body y=0 starts at the top margin.
  • For ordinary business documents, prefer settings.page_margin = 15mm on all sides unless the user requests labels, edge-to-edge backgrounds, or a tighter print format. Plan horizontal and vertical content against the resulting content box before placing elements.
  • Do not create extra pages, blank pages, or forced pagination when the content can fit cleanly on one page. Use table, stack, or container pagination only for real overflow.
  • Without page_margin, auto-paginated continuation pages start at settings.pagination.continuation_top_gap, or at header.height + settings.pagination.continuation_top_gap_with_header when a header exists.

Settings rules:

  • settings.defaults accepts only text, stroke, fill, and shape.
  • settings.metadata accepts title, author, subject, creator, producer, and language.
  • settings.output.mode is binary or file; both return the same PDF bytes, with different Content-Disposition. settings.output.file_name is sanitized and .pdf is appended automatically.
  • settings.pagination controls auto-paginated continuation start offsets when no page_margin is configured. continuation_top_gap defaults to 8mm. continuation_top_gap_with_header defaults to 5mm after header.height. These fields do not move first-page elements. With settings.page_margin or pages[].margin, continuation content starts at the next page content-box top.
  • settings.security is only for ordinary POST /api/v1/pdf/render output. It supports algorithm (aes_128 or aes_256), open_password, owner_password, and permission flags: print, print_high_quality, modify, copy, annotate, fill_forms, extract_accessibility, assemble.
  • open_password enables password-to-open encryption. owner_password grants full rights and must differ from open_password. Restricting any permission flag requires owner_password.
  • Do not combine settings.security with settings.profile or settings.e_invoice.
  • settings.e_invoice belongs to POST /api/v1/e-invoice/render; sending it to JSON Render returns API-002.

Template Render rules:

  • template_id is required and is an opaque template identifier.
  • data is required, must contain 1..=10 objects, and each object contains template-defined fields.
  • Dotted paths such as shipper.name are supported by templates. Empty or whitespace-only strings count as missing required template fields.
  • output follows the same OutputSettings object as JSON Render.

E-Invoice rules:

  • E-Invoice requests use the DocumentRequest shape, require settings.e_invoice, and require settings.profile = "pdfa-3b" or an omitted profile that defaults to pdfa-3b.
  • settings.e_invoice.standard is factur_x or zugferd. profile is currently en16931. document_type is currently invoice.
  • settings.e_invoice.xml requires format = "cii", optional encoding = "utf8", and non-empty UTF-8 XML content up to 2 MiB.
  • delivery.mode is inline_pdf or object. inline_pdf returns PDF bytes; object returns a job descriptor and artifact URLs. url_ttl_seconds is 1..=900.
  • validation.level is basic or strict. validation.execution is sync or async. strict validation requires delivery.mode = "object"; async validation requires strict + object delivery. fail_on_warnings defaults false.
  • report.enabled creates report.json and requires delivery.mode = "object".
  • retention.ttl_hours is 1..=23. retention.store_request stores the original request body as an artifact.
  • data_residency.mode is auto, eu, or global. country is ISO 3166-1 alpha-2. strict = true makes ambiguous or missing residency a hard error.
  • job_id is an optional idempotency identifier for object delivery. UUID v7 is recommended.

Layer and section rules:

  • layers.background and layers.stamp use repeat = all_pages | first_page | last_page plus elements[]. They allow lightweight elements only: text, barcode, image, rect, line, circle, ellipse, polygon, path, link, and container. They do not allow table or stack.
  • layers.watermark requires template and layout, with optional repeat, opacity, and style. The public template type is text. Layout presets are center, tile, diagonal_tile, arc_outside, arc_inside, and wave. Layout fields include angle, gap_x, gap_y, offset_x, offset_y, stagger_x, center_x, center_y, radius, start_x, start_y, amplitude, and wavelength.
  • Path-text watermark presets arc_outside, arc_inside, and wave are limited to a single line and at most 32 grapheme clusters.
  • header.height and footer.height are required. Header elements render in physical page coordinates and do not inherit page margins. Footer x values are physical page coordinates; footer y values are written relative to the top of the footer region before the renderer shifts them to the page bottom. To align header or footer content with body content when page_margin.left=15, set header/footer x values around 15 rather than 0.

Link rules:

  • Element-level links use link: { "target": ... }.
  • URL links use { "target": { "type": "url", "url": "https://..." } }. Supported schemes are http, https, mailto, and tel.
  • Page links use { "target": { "type": "page", "page": 1, "x": 10, "y": 20 } }. page is 1-based.
  • Standalone hotspot elements use type: "link" with x or x_anchor, y, width, height, and target. They may also include alt, padding, border, z_index, and comment.
  • x_anchor.reference can be page_left, page_right, content_left, content_right, table_left, or table_right, with optional offset.

4. Element Typings

Supported pages[].elements[] types:

  • All positioned body elements may include rotation, z_index, comment, and link unless their own schema overrides the base. Most positioned elements require y plus exactly one of x or x_anchor.
  • text: content can be a string, { "spans": [...] }, or block text { "blocks": [...] }. Provide y, content, and exactly one of x or x_anchor. Use style for simple text/spans; use frame, defaults, and block nodes for richer layout. Block nodes support paragraph, list, and page_break. Inline nodes support text, variable, line_break, and tab. JSON Render publicly guarantees system variables page and total_pages.
  • barcode: provide format, content, width, height, y, and exactly one of x or x_anchor. style supports color and fill. options is an object. For QR and other 2D matrix codes, use equal width and height and omit barcode_text by default because encoded content is usually too long to render below the symbol. For 1D linear barcodes, width and height may differ; use barcode_text only when a short human-readable code should appear with the bars. barcode_text supports enabled, content, position top/bottom, offset, and style.
  • Barcode formats: qrcode, qr, microqr, micro-qr, pdf417, micropdf417, micro-pdf417, datamatrix, data-matrix, gs1datamatrix, gs1-datamatrix, gs1_datamatrix, aztec, maxicode, gs1qrcode, gs1-qrcode, gs1_qr, gs1-qr, code128, code-128, code128a, code-128a, code128b, code-128b, code128c, code-128c, gs1128, gs1-128, code39, code-39, code93, code-93, codabar, ean8, ean-8, ean13, ean-13, upca, upc-a, upce, upc-e, itf, interleaved2of5, itf14, itf-14, gtin8, gtin-8, gtin12, gtin-12, gtin13, gtin-13, gtin14, gtin-14, isbn, isbn-13, sscc, sscc-18, msi, msi-plessey, msi10, msi-10, msi11, msi-11, msi1010, msi-1010, msi1110, msi-1110, upus10, s10, uspsimb, usps-imb, intelligent-mail, upcacomposite, upca-composite, upcecomposite, upce-composite.
  • image: provide width, height, y, and exactly one of x or x_anchor. Use top-level asset with optional format, or explicit source. source.kind is asset with key/format or base64 with format/payload. Supported image formats are jpg, jpeg, png, svg, and webp. Do not use Data URI strings or invented image URLs.
  • line: requires x1, y1, x2, y2, with optional stroke and marker.
  • rect: requires y, width, height, and x or x_anchor, with optional fill, stroke, and corner_radius.
  • circle: requires cx, cy, and r, with optional fill and stroke.
  • ellipse: requires cx, cy, rx, and ry, with optional fill and stroke.
  • polygon: requires at least three points, each with x and y, with optional fill and stroke.
  • path: controlled native vector outline. It requires y, width, height, view_box, and d, plus exactly one of x or x_anchor. d is SVG path data for geometry only, for example M 0 0 L 100 0 L 100 40 Z; it is not a full SVG element and cannot carry , , CSS, transform, gradient, or url(#...). view_box defines the local coordinate space for d and must be an object such as { "x": 0, "y": 0, "width": 100, "height": 100 }. d supports M/L/H/V/Q/C/S/T/A/Z plus lowercase relative variants; it must start with M/m, expand to at most 1024 normalized segments, contain at least one drawing segment, and keep all coordinates and control points within view_box. fill, stroke, arbitrary numeric rotation, z_index, comment, and link are supported; fill/stroke use solid color styles. For complex artwork or gradients, prefer image with svg/png/webp or multiple simple solid-color paths. stroke.width is in page-space millimetres and is not scaled by view_box; stroke.compound is not supported.
  • link: standalone clickable hotspot. It requires y, width, height, and target, plus x or x_anchor.
  • container: geometric group for cards, address blocks, status badges, totals blocks, bordered groups, clipped panels, and nested groups. It requires type, y, width, height, and elements; provide x or x_anchor for placement. Optional fields are fill, stroke, corner_radius, padding, layout, overflow, defaults, link, z_index, and comment. Child coordinates are relative to the content box after padding. Container elements can contain text, barcode, image, line, rect, circle, ellipse, polygon, path, link, and container. They cannot contain table or stack.
  • table: public table schema uses x, y, optional width, required columns[], required rows[], plus cell, header, row_header, body, grid, and pagination. Columns require key and width; width modes are fixed, percent, and auto. Rows can use scalar/block text values or complex cells with content, image, barcode, row_span, col_span, style, and link. Legacy fields data, layout, theme, row_headers, corner, and style_overrides are not public inputs.
  • stack: sequential layout for a table followed by one or more block children. Use it for invoice line-item tables followed by subtotal, tax, grand total, payment notes, or signature blocks that must stay directly after the rendered table. It is allowed only in pages[].elements; children requires at least two items; the first child must be table, later children must be block. block children contain lightweight elements and do not have their own x, y, width, or height.

Style objects:

  • TextStyle: font_family, font_mode, font_size, font_weight, font_style, color, opacity, letter_spacing, highlight, line_height, width, height, text_align, vertical_align, direction, text_overflow, shrink_to_fit, min_font_size, wrap_policy, script, decoration, and link_style.
  • InlineTextStyle is the inline subset of TextStyle without layout-only fields such as width and height.
  • barcode_text.style and table-cell text style must not include frame-like layout fields: width, height, vertical_align, text_overflow, shrink_to_fit, or min_font_size. Use parent barcode/table dimensions, table column widths, padding, content_offset_x/content_offset_y, barcode_text.offset, and text_align instead.
  • ParagraphStyle: align, direction, line_height, space_before, space_after, indent_left, indent_right, indent_first_line, hanging_indent, keep_together, keep_with_next, widow_orphan_control, and tabs.
  • StrokeStyle: color, width, opacity, cap, join, miter_limit, dash, and compound.
  • DashStyle uses preset solid/dashed/dotted/custom plus optional pattern and phase. CompoundStrokeStyle currently supports kind = "double" with gap. MarkerStyle supports start/end none, arrow, open_arrow, circle, or bar, plus size.
  • FillStyle: color, opacity, and rule.
  • BlockTextFrame: width, height, vertical_align, overflow, shrink_to_fit, min_font_size, padding, stroke, fill, columns, and column_gap.
  • BarcodeStyle: color and fill.
  • Table style objects include padding, text, fill, content offsets, borders, header rows, row_header, body, grid, and pagination controls. Optional stroke values can be false to disable a border line.

Stack layout rules:

  • Use stack for public table-first flows. The canonical invoice pattern is table first, then one or more block children for subtotal, tax, grand total, payment instructions, or approval/signature rows.
  • Do not use container to wrap a table plus totals. Container descendants cannot be table or stack. If a table needs follow-up content, use stack; if the follow-up content needs a bordered totals card, put a container inside a stack block.
  • The first stack child supplies the table x/y/width. Later block children render after the previous child plus stack.gap. Their inner elements use local y coordinates within the block.
  • Use x_anchor.reference = table_right for right-aligned totals that should follow the table width. When percent or auto table columns are used with table_left/table_right anchors, declare table.width.
  • Treat subtotal, tax, and paid/grand-total rows as one visual totals group. If the group uses a filled or stroked background box, keep a consistent 2mm inner inset from the box edges: use the same table_right offset = 2 for all right-aligned amount values, align labels to a matching 2mm left inset, and do not mix different amount-text offsets inside the same totals group.
  • Do not put stack in header, footer, document layers, or container descendants.

Container layout rules:

  • Use container instead of separate rect plus text when a visual group should move, edit, clip, or inherit defaults as one unit.
  • Use absolute layout for cards with fixed local positions. Omitted layout or {} means { "type": "absolute" }.
  • Use linear layout for deterministic one-dimensional groups such as address lines, badges, label rows, and totals rows. layout.type must be linear before using axis, gap, main_align, cross_align, or wrap.
  • layout.axis is horizontal or vertical. Do not use row, column, flex_direction, justify_content, align_items, flex, grow, shrink, percentage sizing, auto margin, CSS, HTML, or DOM terms.
  • layout.main_align values are start, center, end, and space_between. layout.cross_align values are start, center, end, and stretch. layout.wrap is a boolean.
  • overflow is visible, clip, or paginate. Use visible for normal groups, clip when child drawing must be clipped to the container outer box, and paginate only for body-flow containers that must continue across pages. In a paginated container, descendant text splits only when that text item explicitly uses frame.overflow = "paginate"; otherwise child items move whole to continuation fragments.
  • If a container has a top-level link, do not put element-level links or standalone link items inside it.
  • Do not output container alias fields: background, border, radius, children, margin, row, column, rotation, or y_anchor. Use fill, stroke, corner_radius, elements, layout.axis, and x_anchor instead.
  • Do not output removed style fields as active schema: TextStyle.background, InlineTextStyle.background, BlockTextFrame.background, BlockTextFrame.border, BarcodeStyle.background_color, or highlight.radius. Use highlight, BlockTextFrame.fill, BlockTextFrame.stroke, BarcodeStyle.fill, and highlight.corner_radius.

5. AI Safety, Fonts, and Testing

Strict syntax constraints:

  • Keep the payload limited to public DocumentRequest fields.
  • Put endpoint metadata, headers, bearer tokens, and auth outside the JSON payload.
  • Keep generated elements inside the page or content box.
  • Ask for an asset key or base64 source when the user wants a real logo/image and has not provided one; otherwise use a text or shape placeholder.

Fonts and CJK fallback:

  • If no font_family is declared, gPdf automatically selects bundled fonts that cover the text, including common CJK text.
  • If you declare a Latin/default family such as NotoSans-Regular and the same text may contain Chinese, Japanese, or Korean characters, set "font_mode": "prefer" in the same style object.
  • A declared font_family without font_mode = "prefer" is strict. Font coverage failures return API-002; auto/prefer fallback exhaustion returns API-504.

Sandbox testing:

  • URL: POST https://gpdf.com/api/playground?endpoint=pdf-render
  • Auth: no Authorization header.
  • Limits: 60 requests per minute per IP and 256 KiB JSON request body.
  • Output: application/pdf on success.
  • Sandbox PDFs include the forced watermark gpdf.com Sandbox - Test Only and are not production output.

Production boundary:

  • Use https://api.gpdf.com/api/v1/pdf/render with a bearer token for production API rendering.
  • Common public error codes include API-001 through API-010, API-101 through API-103, API-201 through API-204, API-501 through API-507, and API-900 through API-902 plus API-999.

6. Complete Reference JSON Payload

Below is a valid one-page A4 business invoice payload. It demonstrates the common page margin, physical header/footer alignment, a table-first stack, and a totals group attached to the rendered table bottom. Use it as a practical layout foundation; consult OpenAPI for exact schema details when adding less common fields.

{
  "settings": {
    "profile": "pdfa-2b",
    "metadata": {
      "title": "Invoice INV-2026-8802",
      "author": "gPdf Redesign Corp",
      "subject": "Optimization Services"
    },
    "output": {
      "mode": "binary",
      "file_name": "invoice-2026-8802.pdf"
    },
    "page_margin": {
      "top": 15,
      "right": 15,
      "bottom": 15,
      "left": 15
    },
    "defaults": {
      "text": {
        "font_family": "NotoSans-Regular",
        "font_mode": "prefer",
        "font_size": 9,
        "color": "#374151"
      },
      "stroke": {
        "color": "#D1D5DB",
        "width": 0.25
      },
      "fill": {
        "color": "#FFFFFF",
        "opacity": 1
      },
      "shape": {
        "corner_radius": 1.5
      }
    }
  },
  "header": {
    "height": 16,
    "elements": [
      {
        "type": "text",
        "x": 15,
        "y": 8,
        "style": {
          "width": 90,
          "font_size": 9,
          "font_weight": "bold",
          "color": "#111827"
        },
        "content": "gPdf Redesign Corp"
      },
      {
        "type": "text",
        "x": 120,
        "y": 8,
        "style": {
          "width": 75,
          "font_size": 8,
          "text_align": "right",
          "color": "#6B7280"
        },
        "content": "Generated with gPdf JSON Render"
      }
    ]
  },
  "footer": {
    "height": 10,
    "elements": [
      {
        "type": "text",
        "x": 15,
        "y": 3,
        "style": {
          "width": 180,
          "font_size": 7.5,
          "text_align": "center",
          "color": "#9CA3AF"
        },
        "content": "Confidential sample document"
      }
    ]
  },
  "pages": [
    {
      "size": "a4",
      "elements": [
        {
          "type": "text",
          "x": 0,
          "y": 8,
          "style": {
            "width": 180,
            "font_family": "NotoSans-Regular",
            "font_mode": "prefer",
            "font_size": 24,
            "font_weight": "bold",
            "color": "#1F2937"
          },
          "content": "INVOICE"
        },
        {
          "type": "text",
          "x": 0,
          "y": 24,
          "style": {
            "width": 100,
            "font_size": 9,
            "line_height": 1.3,
            "color": "#4B5563"
          },
          "content": "gPdf Redesign Corp\nSuite 101, Cloudflare Hub\nSan Francisco, CA"
        },
        {
          "type": "text",
          "x": 110,
          "y": 24,
          "style": {
            "width": 70,
            "font_size": 9,
            "text_align": "right",
            "line_height": 1.3,
            "color": "#4B5563"
          },
          "content": "Invoice #: INV-2026-8802\nDate: 2026-05-25\nDue Date: 2026-06-25"
        },
        {
          "type": "rect",
          "x": 0,
          "y": 46,
          "width": 180,
          "height": 0.5,
          "fill": { "color": "#D1D5DB" }
        },
        {
          "type": "stack",
          "gap": 5,
          "children": [
            {
              "type": "table",
              "x": 0,
              "y": 56,
              "width": 180,
              "columns": [
                {
                  "key": "description",
                  "header": "Description",
                  "width": { "mode": "auto" },
                  "cell": { "text": { "text_align": "left" } },
                  "header_cell": { "text": { "font_weight": "bold" } }
                },
                {
                  "key": "qty",
                  "header": "Qty",
                  "width": { "mode": "fixed", "value": 18 },
                  "cell": { "text": { "text_align": "right" } },
                  "header_cell": { "text": { "font_weight": "bold", "text_align": "right" } }
                },
                {
                  "key": "unit_price",
                  "header": "Unit",
                  "width": { "mode": "fixed", "value": 30 },
                  "cell": { "text": { "text_align": "right" } },
                  "header_cell": { "text": { "font_weight": "bold", "text_align": "right" } }
                },
                {
                  "key": "amount",
                  "header": "Amount",
                  "width": { "mode": "fixed", "value": 32 },
                  "cell": { "text": { "text_align": "right" } },
                  "header_cell": { "text": { "font_weight": "bold", "text_align": "right" } }
                }
              ],
              "rows": [
                {
                  "description": "S-Tier GEO Optimization and RAG Services",
                  "qty": 1,
                  "unit_price": "$2,000.00",
                  "amount": "$2,000.00"
                },
                {
                  "description": "Custom JSON-to-PDF layout setup",
                  "qty": 1,
                  "unit_price": "$500.00",
                  "amount": "$500.00"
                }
              ],
              "cell": {
                "padding": { "x": 2, "y": 2 },
                "text": { "font_size": 8.5 },
                "borders": {
                  "bottom": { "color": "#E5E7EB", "width": 0.2 }
                }
              },
              "header": {
                "show": true,
                "repeat_on_page_break": true,
                "cell": {
                  "fill": { "color": "#F3F4F6", "opacity": 1 },
                  "text": { "font_weight": "bold", "color": "#111827" }
                }
              },
              "grid": {
                "horizontal": { "color": "#E5E7EB", "width": 0.2 },
                "vertical": false
              }
            },
            {
              "type": "block",
              "elements": [
                {
                  "type": "rect",
                  "y": 0,
                  "width": 78,
                  "height": 28,
                  "fill": { "color": "#F9FAFB", "opacity": 1 },
                  "stroke": { "color": "#D1D5DB", "width": 0.2 },
                  "corner_radius": 1.5,
                  "x_anchor": { "reference": "table_right", "offset": 0 }
                },
                { "type": "text", "x": 104, "y": 3, "content": "Subtotal", "style": { "width": 40, "font_size": 8 } },
                { "type": "text", "y": 3, "content": "$2,500.00", "style": { "width": 32, "font_size": 8, "text_align": "right" }, "x_anchor": { "reference": "table_right", "offset": 2 } },
                { "type": "text", "x": 104, "y": 10, "content": "Tax", "style": { "width": 40, "font_size": 8 } },
                { "type": "text", "y": 10, "content": "$200.00", "style": { "width": 32, "font_size": 8, "text_align": "right" }, "x_anchor": { "reference": "table_right", "offset": 2 } },
                { "type": "line", "x1": 104, "y1": 18, "x2": 178, "y2": 18, "stroke": { "color": "#9CA3AF", "width": 0.3 } },
                { "type": "text", "x": 104, "y": 21, "content": "Total due", "style": { "width": 40, "font_size": 9, "font_weight": "bold" } },
                { "type": "text", "y": 21, "content": "$2,700.00", "style": { "width": 32, "font_size": 9, "font_weight": "bold", "text_align": "right" }, "x_anchor": { "reference": "table_right", "offset": 2 } }
              ]
            },
            {
              "type": "block",
              "elements": [
                {
                  "type": "barcode",
                  "format": "qrcode",
                  "x": 0,
                  "y": 2,
                  "width": 28,
                  "height": 28,
                  "content": "https://gpdf.com/verify/INV-2026-8802",
                  "link": {
                    "target": {
                      "type": "url",
                      "url": "https://gpdf.com/verify/INV-2026-8802"
                    },
                    "alt": "Verify invoice"
                  }
                },
                {
                  "type": "text",
                  "x": 36,
                  "y": 2,
                  "style": {
                    "width": 144,
                    "font_size": 8.5,
                    "line_height": 1.35,
                    "color": "#6B7280"
                  },
                  "content": "Thank you for partnering with gPdf!\nTo verify the authenticity of this document, scan the QR code to pull our secure record."
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}

7. Container Reference Examples

Use these complete payloads as small, copyable patterns.

7.1 Absolute card

{
  "pages": [
    {
      "size": "a4",
      "elements": [
        {
          "type": "container",
          "x": 20,
          "y": 24,
          "width": 84,
          "height": 34,
          "fill": { "color": "#F8FAFC", "opacity": 1 },
          "stroke": { "color": "#CBD5E1", "width": 0.3 },
          "corner_radius": 3,
          "padding": { "top": 5, "right": 6, "bottom": 5, "left": 6 },
          "elements": [
            {
              "type": "text",
              "x": 0,
              "y": 0,
              "style": { "width": 72, "font_size": 8, "color": "#64748B" },
              "content": "Payment status"
            },
            {
              "type": "text",
              "x": 0,
              "y": 10,
              "style": { "width": 72, "font_size": 15, "font_weight": "bold", "color": "#0F172A" },
              "content": "Paid"
            }
          ]
        }
      ]
    }
  ]
}

7.2 Linear address block

{
  "pages": [
    {
      "size": "label_100_150",
      "elements": [
        {
          "type": "container",
          "x": 8,
          "y": 18,
          "width": 84,
          "height": 40,
          "padding": { "top": 4, "right": 5, "bottom": 4, "left": 5 },
          "layout": {
            "type": "linear",
            "axis": "vertical",
            "gap": 2,
            "main_align": "start",
            "cross_align": "stretch",
            "wrap": false
          },
          "defaults": {
            "text": { "font_family": "NotoSans-Regular", "font_mode": "prefer", "font_size": 9, "color": "#111827" }
          },
          "elements": [
            { "type": "text", "x": 0, "y": 0, "style": { "width": 74, "font_weight": "bold" }, "content": "Ada Lovelace" },
            { "type": "text", "x": 0, "y": 0, "style": { "width": 74 }, "content": "12 Example Street" },
            { "type": "text", "x": 0, "y": 0, "style": { "width": 74 }, "content": "London SW1A 1AA" }
          ]
        }
      ]
    }
  ]
}

7.3 Nested badge

{
  "pages": [
    {
      "size": "a4",
      "elements": [
        {
          "type": "container",
          "x": 20,
          "y": 30,
          "width": 112,
          "height": 28,
          "fill": { "color": "#F9FAFB" },
          "stroke": { "color": "#E5E7EB", "width": 0.25 },
          "corner_radius": 2,
          "padding": { "top": 4, "right": 5, "bottom": 4, "left": 5 },
          "elements": [
            { "type": "text", "x": 0, "y": 3, "style": { "width": 64, "font_size": 10, "font_weight": "bold" }, "content": "Shipment" },
            {
              "type": "container",
              "x": 72,
              "y": 0,
              "width": 30,
              "height": 12,
              "fill": { "color": "#DCFCE7" },
              "stroke": { "color": "#86EFAC", "width": 0.2 },
              "corner_radius": 6,
              "padding": { "top": 2, "right": 4, "bottom": 2, "left": 4 },
              "elements": [
                { "type": "text", "x": 0, "y": 0, "style": { "width": 22, "font_size": 7, "font_weight": "bold", "text_align": "center", "color": "#166534" }, "content": "READY" }
              ]
            }
          ]
        }
      ]
    }
  ]
}

7.4 Clip panel

{
  "pages": [
    {
      "size": "a4",
      "elements": [
        {
          "type": "container",
          "x": 24,
          "y": 42,
          "width": 60,
          "height": 22,
          "fill": { "color": "#EFF6FF" },
          "stroke": { "color": "#93C5FD", "width": 0.25 },
          "corner_radius": 3,
          "overflow": "clip",
          "elements": [
            { "type": "rect", "x": 42, "y": -8, "width": 28, "height": 28, "fill": { "color": "#BFDBFE", "opacity": 1 } },
            { "type": "text", "x": 5, "y": 7, "style": { "width": 45, "font_size": 9, "font_weight": "bold", "color": "#1E3A8A" }, "content": "Clipped note" }
          ]
        }
      ]
    }
  ]
}

7.5 Paginated body container

Use "overflow": "paginate" only on containers inside pages[].elements or nested inside another body-flow container. Do not use it in headers, footers, layers, or stack blocks. The container height is the first-fragment height; content that does not fit moves to continuation pages.

{
  "settings": {
    "metadata": {
      "title": "Container paginate example"
    }
  },
  "pages": [
    {
      "width": 80,
      "height": 28,
      "elements": [
        {
          "type": "container",
          "x": 4,
          "y": 4,
          "width": 48,
          "height": 16,
          "overflow": "paginate",
          "fill": { "color": "#F8FAFC" },
          "stroke": { "color": "#2563EB", "width": 0.4 },
          "padding": { "top": 1, "right": 1, "bottom": 1, "left": 1 },
          "elements": [
            {
              "type": "text",
              "x": 0,
              "y": 0,
              "content": "Container paginate first fragment",
              "style": { "width": 42, "font_size": 8 }
            },
            {
              "type": "text",
              "x": 0,
              "y": 30,
              "content": "Container paginate continuation",
              "style": { "width": 42, "font_size": 8 }
            }
          ]
        }
      ]
    }
  ]
}