---
title: "Build From Pdf"
method: POST
path: "/v2/invoice-pdf-templates/build-from-pdf"
tags: ["invoice-pdf-templates"]
---

# Build From Pdf

`POST /v2/invoice-pdf-templates/build-from-pdf`

## Request

- Base URL: `https://api.stuut.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://api.stuut.ai/v2/invoice-pdf-templates/build-from-pdf`
- Auth: HTTP bearer

Draft a Template From an Invoice PDF

Reads a PDF the organization's own billing system printed (one invoice, or several, with any
terms pages) and drafts the template that prints like it: the closest layout, the elements it
prints, issuer and payment details as printed, line-item columns, header fields and terms.
The logo is cut out of page 1 and stored, so the draft's `logo_url` is ready to use. Nothing
else is saved; pass the draft's `config` to `createTemplate`. Bank details are copied from the
page and listed under `review` for checking. PDF only, up to 20 MB. Requires admin access.

## Request body `multipart/form-data`

- BodyPostInvoicePdfTemplatesBuildFromPdf
  - `file` string, binary, required

## Response `200`

Successful Response

- InvoicePdfTemplateBuildResult: A template drafted from the organization's own invoice PDF, for the admin to review and create with `createTemplate`. Nothing is saved by the build.
  - `document` InvoicePdfDocumentShape, required: What the uploaded file turned out to be.
    - `page_count` integer, required
    - `invoice_count` integer, required
    - `terms_pages` integer[], required
    - `language` string, required
  - `name` string, required
  - `layout_name` string, required
  - `layout_reason` string, required
  - `config` InvoicePdfTemplateDraft, required: Drafted settings in the shape `createTemplate` and `updateTemplate` take. Its own class so the request schema is only ever an input: a schema used both ways is generated as two types.
    - `state` 'active' | 'disabled', required
    - `action` 'generate' | 'never_generate', required
    - `combine_pdfs_from` integer, nullable, required
    - `show_org_contact` boolean, nullable, required
    - `show_mailing_address` boolean, nullable, required
    - `show_banking` boolean, nullable, required
    - `show_ship_to` boolean, nullable, required
    - `show_bill_to` boolean, nullable, required
    - `show_purchase_order_number` boolean, nullable, required
    - `show_order_number` boolean, nullable, required
    - `show_customer_number` boolean, nullable, required
    - `show_payment_terms` boolean, nullable, required
    - `show_invoice_method` boolean, nullable, required
    - `show_due_date` boolean, nullable, required
    - `show_invoice_period` boolean, nullable, required
    - `show_invoice_balance` boolean, nullable, required
    - `show_tax_row` boolean, nullable, required
    - `show_payments_row` boolean, nullable, required
    - `show_comments` boolean, nullable, required
    - `show_late_fee_note` boolean, nullable, required
    - `show_payment_instructions` boolean, nullable, required
    - `show_terms` boolean, nullable, required
    - `show_payment_stub` boolean, nullable, required: Print the tear-off remittance stub. Only layouts that have one print it; the rest ignore it.
    - `mailing_address` PdfAddressSchemaOutput, required: Remit-to / wire address.
      - `name` string, nullable, required
      - `line1` string, nullable, required
      - `line2` string, nullable, required
      - `city` string, nullable, required
      - `state` string, nullable, required
      - `postal_code` string, nullable, required
      - `country` string, nullable, required
    - `wire_address` PdfAddressSchemaOutput, required: Remit-to / wire address.
      - `name` string, nullable, required
      - `line1` string, nullable, required
      - `line2` string, nullable, required
      - `city` string, nullable, required
      - `state` string, nullable, required
      - `postal_code` string, nullable, required
      - `country` string, nullable, required
    - `lockbox_address` PdfAddressSchemaOutput, required: Remit-to / wire address.
      - `name` string, nullable, required
      - `line1` string, nullable, required
      - `line2` string, nullable, required
      - `city` string, nullable, required
      - `state` string, nullable, required
      - `postal_code` string, nullable, required
      - `country` string, nullable, required
    - `banking` PdfBankDetailsSchemaOutput, required: Where customers wire or ACH payments. Written as a whole: an update replaces every field in it.
      - `bank_name` string, nullable, required
      - `account_number` string, nullable, required
      - `routing_number` string, nullable, required
      - `wire_routing_number` string, nullable, required
      - `details` string, nullable, required
    - `payment_terms` string, nullable, required
    - `invoice_method` string, nullable, required
    - `late_fee_note` string, nullable, required
    - `footer_note` string, nullable, required
    - `notes` string, nullable, required
    - `payment_instructions` string, nullable, required
    - `org_contact_lines` string[], nullable, required
    - `accent_color` string, nullable, required
    - `layout_name` string, nullable, required
    - `logo_url` string, nullable, required
    - `company_name` string, nullable, required
    - `header_fields` PdfHeaderFieldSchema[], nullable, required
      - `source` 'invoice' | 'partner', required: Whose custom fields a header field reads.
      - `key` string, required
      - `label` string, required
    - `terms_blocks` PdfTermsBlockSchemaOutput[], nullable, required
      - `title` string, required
      - `subtitle` string, nullable, required
      - `body` string, required
    - `terms_placement` 'side_by_side' | 'stacked', required
    - `line_item_columns` PdfLineItemColumnSchemaOutput[], nullable, required
      - `field` 'line_number' | 'quantity' | 'item' | 'name' | 'description' | 'product_type' | 'period' | 'unit_amount' | 'total_discount' | 'total_tax' | 'total_amount' | 'custom_field', required
      - `key` string, nullable, required
      - `label` string, nullable, required
    - `payment_link` PdfPaymentLinkSchemaOutput, required: A pay-online link printed above the totals. `erp_payment_url` prints the payment link the ERP synced onto the invoice; `custom_field` prints the invoice custom field `key`, and only it has a `key`. Left off an invoice with no link, or whose link isn't an https URL. `image_url` prints either side of the link, such as the payment provider's badge; upload it like the logo.
      - `source` 'erp_payment_url' | 'custom_field', required: Where a template's pay-online link comes from. Both are the ERP's: the invoice's synced payment link, or an invoice custom field the template names.
      - `key` string, nullable, required
      - `image_url` string, nullable, required
    - `totals_rows` PdfTotalsRowSchemaOutput[], nullable, required: The totals block top to bottom. `null` prints subtotal, tax, total, payments and amount due as `show_tax_row`, `show_payments_row` and `show_invoice_balance` allow; a list decides the rows and those three switches no longer apply.
      - `source` 'subtotal' | 'tax' | 'total' | 'payments' | 'amount_due' | 'custom_field', required
      - `key` string, nullable, required
      - `label` string, nullable, required
    - `labels` object, nullable, required: Captions to print instead of the layout's own, keyed by caption, in any language. A key left out keeps the layout's wording; `null` clears every rename. The English wording each key stands for: `invoice` = Invoice; `invoice_no` = Invoice no.; `invoice_date` = Invoice date; `customer_no` = Customer no.; `bill_to` = Bill to; `ship_to` = Ship to; `terms` = Terms; `due_date` = Due date; `po` = PO #; `sales_order` = Sales order #; `invoice_method` = Sent via; `period` = Service period; `comments` = Comments; `subtotal` = Subtotal; `tax` = Tax; `total` = Total amount; `payments` = Payments; `amount_due` = Total amount due; `detach` = Please detach and return this portion with your payment; `amount_paid` = Amount paid; `payment_options` = Payment options; `by_check` = By check; `by_lockbox` = By courier or lockbox; `by_transfer` = By ACH / wire; `by_ach` = By ACH; `by_wire` = By wire; `account` = Account #; `routing` = Routing #; `wire_routing` = Wire routing #; `page` = Page; `of` = of; `details` = Details; `reference` = Reference; `instructions` = Instructions; `payment_slip` = Payment slip; `from` = From; `amount_enclosed` = Amount enclosed; `balance` = Invoice balance; `lang` = en; `pay_online` = Pay online at the link below.
    - `date_format` '%d/%m/%Y' | '%m/%d/%Y' | '%-m/%-d/%Y' | '%Y-%m-%d' | '%d-%b-%y' | '%d %b %Y' | '%-d %b %Y' | '%b %-d, %Y', required: The date patterns a template may print with (Python strftime). `%b` prints the English month, so a template in another language picks a numeric one.
    - `currency` 'ADP' | 'AED' | 'AFA' | 'AFN' | 'ALK' | 'ALL' | 'AMD' | 'ANG' | 'AOA' | 'AOK' | 'AON' | 'AOR' | 'ARA' | 'ARL' | 'ARM' | 'ARP' | 'ARS' | 'ATS' | 'AUD' | 'AWG' | 'AZM' | 'AZN' | 'BAD' | 'BAM' | 'BAN' | 'BBD' | 'BDT' | 'BEC' | 'BEF' | 'BEL' | 'BGL' | 'BGM' | 'BGN' | 'BGO' | 'BHD' | 'BIF' | 'BMD' | 'BND' | 'BOB' | 'BOL' | 'BOP' | 'BOV' | 'BRB' | 'BRC' | 'BRE' | 'BRL' | 'BRN' | 'BRR' | 'BRZ' | 'BSD' | 'BTN' | 'BUK' | 'BWP' | 'BYB' | 'BYN' | 'BYR' | 'BZD' | 'CAD' | 'CDF' | 'CHE' | 'CHF' | 'CHW' | 'CLE' | 'CLF' | 'CLP' | 'CNH' | 'CNX' | 'CNY' | 'COP' | 'COU' | 'CRC' | 'CSD' | 'CSK' | 'CUC' | 'CUP' | 'CVE' | 'CYP' | 'CZK' | 'DDM' | 'DEM' | 'DJF' | 'DKK' | 'DOP' | 'DZD' | 'ECS' | 'ECV' | 'EEK' | 'EGP' | 'ERN' | 'ESA' | 'ESB' | 'ESP' | 'ETB' | 'EUR' | 'FIM' | 'FJD' | 'FKP' | 'FRF' | 'GBP' | 'GEK' | 'GEL' | 'GHC' | 'GHS' | 'GIP' | 'GMD' | 'GNF' | 'GNS' | 'GQE' | 'GRD' | 'GTQ' | 'GWE' | 'GWP' | 'GYD' | 'HKD' | 'HNL' | 'HRD' | 'HRK' | 'HTG' | 'HUF' | 'IDR' | 'IEP' | 'ILP' | 'ILR' | 'ILS' | 'INR' | 'IQD' | 'IRR' | 'ISJ' | 'ISK' | 'ITL' | 'JMD' | 'JOD' | 'JPY' | 'KES' | 'KGS' | 'KHR' | 'KMF' | 'KPW' | 'KRH' | 'KRO' | 'KRW' | 'KWD' | 'KYD' | 'KZT' | 'LAK' | 'LBP' | 'LKR' | 'LRD' | 'LSL' | 'LTL' | 'LTT' | 'LUC' | 'LUF' | 'LUL' | 'LVL' | 'LVR' | 'LYD' | 'MAD' | 'MAF' | 'MCF' | 'MDC' | 'MDL' | 'MGA' | 'MGF' | 'MKD' | 'MKN' | 'MLF' | 'MMK' | 'MNT' | 'MOP' | 'MRO' | 'MRU' | 'MTL' | 'MTP' | 'MUR' | 'MVP' | 'MVR' | 'MWK' | 'MXN' | 'MXP' | 'MXV' | 'MYR' | 'MZE' | 'MZM' | 'MZN' | 'NAD' | 'NGN' | 'NIC' | 'NIO' | 'NLG' | 'NOK' | 'NPR' | 'NZD' | 'OMR' | 'PAB' | 'PEI' | 'PEN' | 'PES' | 'PGK' | 'PHP' | 'PKR' | 'PLN' | 'PLZ' | 'PTE' | 'PYG' | 'QAR' | 'RHD' | 'ROL' | 'RON' | 'RSD' | 'RUB' | 'RUR' | 'RWF' | 'SAR' | 'SBD' | 'SCR' | 'SDD' | 'SDG' | 'SDP' | 'SEK' | 'SGD' | 'SHP' | 'SIT' | 'SKK' | 'SLE' | 'SLL' | 'SOS' | 'SRD' | 'SRG' | 'SSP' | 'STD' | 'STN' | 'SUR' | 'SVC' | 'SYP' | 'SZL' | 'THB' | 'TJR' | 'TJS' | 'TMM' | 'TMT' | 'TND' | 'TOP' | 'TPE' | 'TRL' | 'TRY' | 'TTD' | 'TWD' | 'TZS' | 'UAH' | 'UAK' | 'UGS' | 'UGX' | 'USD' | 'USN' | 'USS' | 'UYI' | 'UYP' | 'UYU' | 'UYW' | 'UZS' | 'VEB' | 'VED' | 'VEF' | 'VES' | 'VND' | 'VNN' | 'VUV' | 'WST' | 'XAF' | 'XAG' | 'XAU' | 'XBA' | 'XBB' | 'XBC' | 'XBD' | 'XCD' | 'XCG' | 'XDR' | 'XEU' | 'XFO' | 'XFU' | 'XOF' | 'XPD' | 'XPF' | 'XPT' | 'XRE' | 'XSU' | 'XTS' | 'XUA' | 'XXX' | 'YDD' | 'YER' | 'YUD' | 'YUM' | 'YUN' | 'YUR' | 'ZAL' | 'ZAR' | 'ZMK' | 'ZMW' | 'ZRN' | 'ZRZ' | 'ZWD' | 'ZWL' | 'ZWR', required: The 3 character [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code.
  - `unmapped` InvoicePdfPrintedValue[], required
    - `label` string, required
    - `example` string, required
    - `why` string, required
  - `review` InvoicePdfReviewNote[], required
    - `field` string, required
    - `reason` string, required

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/stuut/apis/stuut-api.md) - [All operations](https://skmtc.dev/stuut/apis/stuut-api/llms.txt) - [OpenAPI document](https://skmtc.dev/stuut/apis/stuut-api/revisions/ff0ad16a55ff?raw)
