Purchase order template

Convert purchase order PDF to JSON

Upload a purchase order and get back the PO number, buyer and supplier, ship-to address, dates, terms, totals and each ordered line with its item code, quantity and price.

No account needed for the Playground. The purchase-order template is already picked for you.

At a glance

  • 22 fields, including line_items
  • PDF, PNG and JPEG, including scans and photos
  • Output: JSON, Excel (.xlsx), CSV
  • Built to return null instead of guessing
  • Documents are not stored after a request finishes
  • Good for: sales order entry, three-way matching with invoices, supplier portals and erp imports

Fields

What gets extracted

The purchase-order template, exactly as it is saved in a new workspace. Every key comes back in the response. A value that is not on the document is null.

FieldType
po_numberrequiredPurchase order number.string
order_daterequireddate
delivery_dateRequested or promised delivery date.date
buyer_namerequiredstring
buyer_addressstring
supplier_namerequiredstring
supplier_addressstring
ship_to_addressstring
currencyISO 4217 code, for example USD, EUR, or LKR.string
payment_termsFor example Net 30.string
shipping_methodstring
subtotalnumber
tax_amountnumber
shippingnumber
totalrequirednumber
line_itemsrequiredOne entry per ordered line, in document order.object[]
└ item_codeItem code, part number, or SKU.string
└ descriptionrequiredstring
└ quantityrequirednumber
└ unitUnit of measure, for example pcs or boxes.string
└ unit_pricerequirednumber
└ amountrequiredLine total.number

Key fields

Purchase order fields worth knowing

What the trickier fields in the purchase-order template hold, and how they relate.

  • po_number

    The buyer's order number. Invoices that quote it return it as purchase_order_number in the invoice template, so orders and invoices can be joined.

  • delivery_date and ship_to_address

    delivery_date is the requested or promised delivery date. ship_to_address is where the goods go, which is often a warehouse rather than buyer_address.

  • line_items[].item_code

    The part number or SKU as printed, with leading zeros and letter case kept. Use it with quantity and unit_price to match ordered lines to invoice lines.

Example

From purchase order to JSON

An illustrative purchase order with a made-up company and numbers, and the JSON the purchase-order template returns for it. Fields that are not on the document come back as null.

Input: made-up example purchase order
Scanned Acme Studio purchase order PO-7781 to Northwind Supply Ltd, dated 18 Oct 2026 for delivery by 01 Nov 2026, with 4 Cat6 cables and 2 network switches totalling USD 1,280.50, signed and stamped
Output: values
{
  "po_number": "PO-7781",
  "order_date": "2026-10-18",
  "delivery_date": "2026-11-01",
  "buyer_name": "Acme Studio (Pvt) Ltd",
  "buyer_address": "45 Flower Road, Colombo 07",
  "supplier_name": "Northwind Supply Ltd",
  "supplier_address": "12 Harbour Road, Colombo 03",
  "ship_to_address": "Acme Studio warehouse, 9 Baseline Road, Colombo 09",
  "currency": "USD",
  "payment_terms": "Net 30",
  "shipping_method": "courier",
  "subtotal": 1180,
  "tax_amount": 94.4,
  "shipping": 6.1,
  "total": 1280.5,
  "line_items": [
    {
      "item_code": "CBL-50",
      "description": "Cat6 cable, 50 m",
      "quantity": 4,
      "unit": "pcs",
      "unit_price": 120,
      "amount": 480
    },
    {
      "item_code": "SW-24",
      "description": "Network switch, 24 port",
      "quantity": 2,
      "unit": "pcs",
      "unit_price": 350,
      "amount": 700
    }
  ]
}

Common gotchas

Where purchase order extraction trips up

Things that often catch people out with purchase order data, and how to handle them.

  • Two item codes on one line

    Some POs print both the buyer's and the supplier's part number. The template has one item_code field, so add a second field in the schema editor if you need both.

  • Units of measure

    quantity and unit are copied as printed, so 2 boxes comes back as quantity 2 with unit boxes. Convert to your own stock unit in your code.

  • Tax and shipping lines

    subtotal, tax_amount, shipping and total are separate fields, each copied as printed. A PO with no tax line returns tax_amount as null.

How it works

Three steps, no setup.

  1. Step 1

    Upload the document

    Drop a purchase order into the Playground, or send it base64 encoded to the API. PDF, PNG and JPEG all work.

  2. Step 2

    Pick the template

    Choose the purchase-order schema. It is already in every new workspace and guest browser, and you can edit its fields.

  3. Step 3

    Get typed JSON

    The model fills exactly the schema's keys, with numbers as numbers and dates as yyyy-mm-dd. Copy it or use it from your code.

API

Parse a purchase order with one request

Send the file to POST /api/v1/parse with "schema": "purchase-order". The saved template is used by name, so there is nothing else to send.

Create an API key in your workspace after you sign up. If you deleted or renamed the template, pass the schema definition inline instead of its name. The same call is available to AI agents through the MCP server.

Read the API docs
POST /api/v1/parse
curl -X POST https://doc2json.manoonlabs.com/api/v1/parse \
  -H "Authorization: Bearer $DOC2JSON_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"file_base64\": \"$(base64 -w0 purchase-order.pdf)\", \"schema\": \"purchase-order\"}"

Schema

The purchase-order schema

The JSON Schema behind the purchase-order template. Paste it into the schema editor as a starting point, or send it inline as "schema" in an API request if you deleted or renamed the template.

{
  "type": "object",
  "description": "A purchase order sent by a buyer to a supplier.",
  "properties": {
    "po_number": {
      "type": "string",
      "description": "Purchase order number."
    },
    "order_date": {
      "type": "date"
    },
    "delivery_date": {
      "type": "date",
      "description": "Requested or promised delivery date."
    },
    "buyer_name": {
      "type": "string"
    },
    "buyer_address": {
      "type": "string"
    },
    "supplier_name": {
      "type": "string"
    },
    "supplier_address": {
      "type": "string"
    },
    "ship_to_address": {
      "type": "string"
    },
    "currency": {
      "type": "string",
      "description": "ISO 4217 code, for example USD, EUR, or LKR."
    },
    "payment_terms": {
      "type": "string",
      "description": "For example Net 30."
    },
    "shipping_method": {
      "type": "string"
    },
    "subtotal": {
      "type": "number"
    },
    "tax_amount": {
      "type": "number"
    },
    "shipping": {
      "type": "number"
    },
    "total": {
      "type": "number"
    },
    "line_items": {
      "type": "array",
      "description": "One entry per ordered line, in document order.",
      "items": {
        "type": "object",
        "properties": {
          "item_code": {
            "type": "string",
            "description": "Item code, part number, or SKU."
          },
          "description": {
            "type": "string"
          },
          "quantity": {
            "type": "number"
          },
          "unit": {
            "type": "string",
            "description": "Unit of measure, for example pcs or boxes."
          },
          "unit_price": {
            "type": "number"
          },
          "amount": {
            "type": "number",
            "description": "Line total."
          }
        },
        "required": [
          "description",
          "quantity",
          "unit_price",
          "amount"
        ]
      }
    }
  },
  "required": [
    "po_number",
    "order_date",
    "buyer_name",
    "supplier_name",
    "total",
    "line_items"
  ]
}

FAQ

Purchase order to JSON, answered.

Do purchase orders from different buyers work?

Yes. There is no per-layout setup. The model reads each document and fills the same keys, so POs from different buyers come back in one shape.

Can I import the order lines into a spreadsheet or ERP?

Yes. Download the result as CSV for one row per ordered line with the PO number, buyer and supplier repeated, or as Excel (.xlsx) with the header and lines on separate sheets. Over the API, add export=csv or export=xlsx.

Do you store my purchase order documents?

No. The file is processed in memory for the request and then dropped. Neither the document nor the extracted JSON is saved. Only a usage record is kept, with things like the time, page count and credits used.

Can I change the fields?

Yes. Every new workspace, and every guest browser, starts with the purchase-order template as a normal schema. Edit it, rename keys, add fields or delete it. Changes are yours, and a deleted template does not come back.

What happens when a value is not on the document?

It comes back as null. doc2json is built to return null instead of guessing, so you can tell missing data from real data.

Is it free to try?

Yes. The Playground works without an account, using a small guest allowance. A free account adds monthly credits, saved schemas and an API key. One credit is one page.

Try it on your own purchase order.

Open the Playground with the purchase-order template picked, drop in a file, and see the JSON. Sign up free when you want an API key.