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.
| Field | Type | Description |
|---|---|---|
| po_numberrequiredPurchase order number. | string | Purchase order number. |
| order_daterequired | date | |
| delivery_dateRequested or promised delivery date. | date | Requested or promised delivery date. |
| buyer_namerequired | string | |
| buyer_address | string | |
| supplier_namerequired | string | |
| supplier_address | string | |
| ship_to_address | string | |
| currencyISO 4217 code, for example USD, EUR, or LKR. | string | ISO 4217 code, for example USD, EUR, or LKR. |
| payment_termsFor example Net 30. | string | For example Net 30. |
| shipping_method | string | |
| subtotal | number | |
| tax_amount | number | |
| shipping | number | |
| totalrequired | number | |
| line_itemsrequiredOne entry per ordered line, in document order. | object[] | One entry per ordered line, in document order. |
| └ item_codeItem code, part number, or SKU. | string | Item code, part number, or SKU. |
| └ descriptionrequired | string | |
| └ quantityrequired | number | |
| └ unitUnit of measure, for example pcs or boxes. | string | Unit of measure, for example pcs or boxes. |
| └ unit_pricerequired | number | |
| └ amountrequiredLine total. | number | Line total. |
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.

{
"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.
- 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.
- 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.
- 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 docscurl -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.