Procore keeps purchase orders in the project-level Commitments tool, with the line items on a Schedule of Values. Both the SOV CSV import and the purchase_order_contracts REST API want structured rows. Neither reads a PDF. PurchaseOrders reads the purchase order PDF, scan, or photo and returns the header fields and the full line-item table as Excel, CSV, or JSON, so whatever feeds Procore is typed by a machine instead of a person. Upload a real purchase order below.
Submit your purchase orders
Drop documents here, or click to file
Up to 50 files per batch
Uploading...
Procore is clear about what a purchase order is. In its own words, a PO is a documented financial commitment that details the types, quantities, and agreed-upon prices for products or services. Creating one is quick. Creating three hundred from documents that arrived as PDFs is a different job, and it is the job Procore deliberately leaves to you.
This surprises people. Procore has downloadable import templates for direct costs, budgets, the directory, locations, punch list items, and submittals. Commitments have exactly one entry on that list, and it covers SOV line items only. The Procore Imports desktop application handles cost codes, contacts, locations, punch items, and submittals, and does not handle commitments at all.
The Schedule of Values CSV import adds or replaces line items inside a commitment that already exists. So a hundred purchase orders means a hundred commitments created by hand first, each one then filled from its own file. The import saves the line entry, not the order entry.
Creating purchase orders at volume means POST to purchase_order_contracts, or the sync endpoint for batches. Either way your integration has to supply vendor, number, dates, terms, and every line with its cost code and amount. If the source is an emailed PDF, something upstream has to produce those values.
By default the commitment has to be in Draft status to import SOV line items. The Enable Always Editable Schedule of Values setting relaxes that, but even then you cannot replace line items that have already been invoiced. Discovering this halfway through a migration is a bad afternoon.
Procore is explicit that you must not add or move data columns, because the order matches its database. Rows missing a cost code name, cost code number, line item type, or an amount are skipped. A blank amount cell is rejected outright, so you enter 0.00 instead. Typing errors produce a shorter file, not an error message you can act on.
The CSV does not accept budget codes. You supply the cost code, the cost type, and optionally the sub job segment, and Procore assembles the budget code from those. Anyone building a file from a supplier PO has to map to that structure rather than to what the document says.
PurchaseOrders is the capture step in front of Procore. It is not a Procore integration and it does not run inside Procore. You give it a purchase order document. It gives back clean, field-level data that you map to the SOV CSV template Procore generates for you, or hand to the integration that calls the commitments API.
A digital PDF from a supplier system, a scan of a mailed order, or a phone photo taken in a job trailer. All go through the same extraction, with no per-supplier template to build first.
PO number, vendor, bill-to and ship-to, order and delivery dates, payment terms, ship via, and the line grid: description, quantity, unit of measure, unit price, and extended amount, captured across page breaks.
Output is one row per line item with consistent headers, which is what the Schedule of Values import expects once you have added your cost code, cost type, and line item type columns. Map once, and every later batch drops into the same mapping.
Pull the same extraction as JSON and feed whatever calls purchase_order_contracts and its line_items collection. Clean fields in, no document parsing on your side, and no PDF handling in your integration code.
Upload a stack of orders at once rather than one at a time. That is what turns a migration onto Procore from a staffing problem into a same-day job.
Captured fields are shown on screen so you can correct an odd value before you export. Catching it here is cheaper than finding out a row was silently skipped during the SOV import.
Purchase orders live in the project-level Commitments tool, not at company level. When you create one, Procore asks which type of commitment contract you want, and the two choices are Purchase Order and Subcontract. New purchase orders are always added to the Contracts tab. The header carries contract number, contract company, and title, then general information including status, executed flag, default retainage, bill to, assigned to, payment terms, ship to, ship via, and description. Procore notes that none of the basic information fields are required, though duplicate contract numbers are not permitted and numbering auto-increments. Worth knowing before you plan the work: to create change orders or invoices against a contract, its status has to be Approved or Complete.
Line items sit on the commitment's Schedule of Values, reached from the General tab. Which fields you get depends on the accounting method. An amount-based SOV takes Sub Job, Cost Code, Cost Type, Description, Tax Code, and Amount. A unit or quantity-based SOV adds Quantity, UOM, Unit Price, Subtotal, and an Override option. If your Procore instance is set to a non-US locale you may see this called a Bill of Quantities rather than a Schedule of Values; it is the same object.
Procore generates the template for you rather than publishing a file to download. Open the commitment, go to General, then Schedule of Values, choose Edit, then Import SOV from CSV, and download either a blank template or one prefilled with the existing line items. You choose comma or semicolon as the delimiter, and on import you choose whether to add additional line items or replace the existing ones. Permissions are Admin on the project's Commitments tool, or Read Only or Standard with the Update Purchase Order Contract and Update Work Order Contract granular permissions enabled. The limitation that shapes everything else: this import fills the SOV of a commitment that already exists. There is no native CSV or Excel import in Procore that creates purchase order records in bulk.
For bulk creation the path is the REST API. Purchase orders are purchase_order_contracts, with the collection at /rest/v1.0/purchase_order_contracts for list and create, and line items underneath at /rest/v1.0/purchase_order_contracts/{id}/line_items. Batch work goes through the PATCH .../sync variants, which accept attributes for up to 1000 resources per call, always return HTTP 200, and split the outcome into an entities array for the successes and an errors array for the rest. A resource with no id and no origin_id is created, one with a matching origin_id is updated, which is what makes origin_id the useful column to carry your source document reference in. Procore now recommends the v2.0 commitment contract line item endpoints for new integrations. Note also that GET /rest/v1.0/commitments is read-only and returns purchase orders and subcontracts together, so writes have to go to the specific collection. The API rate limits work on an hourly window plus a ten-second spike window, reported through the X-Rate-Limit headers, and Procore treats those headers as the source of truth rather than any published number.
In the API a subcontract is a work order contract, which is why the permission to create subcontracts is named Create Work Order Contract. The two objects are structurally parallel, and both carry an SOV, change orders, invoices, and compliance documents, but their fields differ in ways that reflect how they are used. A purchase order has assignee, bill to address, ship to address, ship via, payment terms, and delivery date. A work order contract has contract start date, estimated and actual completion dates, signed contract received date, inclusions, and exclusions. The status lists differ too: purchase orders move through Draft, Processing, Submitted, Partially Received, Received, Approved, and Closed, while work order contracts run Draft, Out For Bid, Out For Signature, Approved, Complete, Terminated, and Void. Materials bought against a job are the purchase order case, and that is the one this page is about.
Procore's company-level ERP Integrations connect to Viewpoint Spectrum, Vista, QuickBooks Desktop, QuickBooks Online, Sage 300 CRE, Sage 100 Contractor, Sage Intacct, Yardi Voyager, NetSuite, Acumatica, MRI Platform X, CMiC, Workday, and Xero. Approved commitments can be exported for accounting acceptance, though Procore is careful to say each connector has its own feature set and yours may not support a given action, so check your own. Sending a commitment to ERP generally requires Admin permission on Commitments, a contract company linked to an ERP-integrated vendor, Approved status, and an SOV carrying at least one line with an ERP standard cost code. After export, contract company, title, status, and default retainage are locked. On the Sage 300 CRE connector Procore states that once a project is synced, commitments must always be created in Procore rather than in Sage, which makes the speed of getting orders into Procore an accounting problem as well as a project one.
To be plain about the boundary: PurchaseOrders extracts purchase order data from documents into a structured file. It is not a Procore integration, it does not install in Procore, it does not call the commitments API for you, it does not write to Procore, and it does not create, approve, receive, or match purchase orders or commitments. Those all stay in Procore. We remove the typing that happens before the import, and nothing else.
General contractors whose suppliers send material orders and confirmations as PDFs use it so those figures reach the Commitments tool the same week. Specialty contractors migrating onto Procore use it to build the initial commitment file rather than keying a year of open orders. Project accountants reconciling a supplier PO against what was actually committed use the purchase order PDF to Excel converter to get both sides into a spreadsheet. Integration teams wiring an orders mailbox into their own Procore app use the purchase order API so the code receives JSON rather than an attachment, and row-level accuracy on long material orders is covered in purchase order line item extraction. A migration backlog clears through bulk purchase order upload, the general load pattern is in how to import purchase orders to an ERP, and construction teams usually start at purchase order extraction for construction. Firms whose accounting sits in a system Procore syncs to can also look at purchase order to Sage Intacct and purchase order to Acumatica.
If your ledger is Vista, Procore's Vista connector, built by Ryvit, exports commitments and commitment change orders from Procore to Vista on an automatic hourly sync, and Procore does not support exporting commitments created in Vista into a Procore project. Orders that begin outside both systems, such as supplier confirmations and quotes that arrive as PDFs, need their own load path into Vista, which is set out in Viewpoint Vista purchase order import.
All three end at the same place, a commitment with a populated Schedule of Values. They differ in what happens before it.
| What matters | Manual keying into Commitments | Template OCR tools | PurchaseOrders AI |
|---|---|---|---|
| Setup per supplier layout | None, but slow forever | Build a template each | None, any layout |
| Mixed PDF, scan, job-site photo | Handled by a person | Often breaks | Handled automatically |
| Line-item capture for the SOV | Error-prone by hand | Varies by template | Full line-item tables |
| Time per purchase order | 5 to 10 minutes | 1 to 3 minutes | Under 10 seconds |
| Output shape | Typed straight into the screen | Needs cleanup | Row per line, ready to map |
| Rows silently skipped on import | Typos drive most of them | Some | Fewer, data is reviewed first |
| Cost per PO at volume | High manual labor | Per-page plus setup | Under $2 |
PurchaseOrders.io extracts purchase order data into Excel, CSV, JSON, or an API response that you map to Procore's Schedule of Values columns or hand to your own integration. It is not a Procore integration, does not install in Procore, does not call the Procore API on your behalf, and does not create, approve, receive, or match commitments. Procore is a trademark of Procore Technologies, Inc.; this page is not affiliated with or endorsed by Procore. Manual cost reflects published estimates of $15 to $40 to fully process a purchase order by hand.
No templates to build, no changes inside Procore.
Drag in PDFs, scans, or photos, one at a time or a whole batch pulled from the orders mailbox.
Tip: Mixed suppliers and file types in the same upload are fine.
The AI reads each order and returns the header fields and the complete line-item table in seconds.
Tip: Check the captured values on screen before you export, not after the SOV import silently skips a row.
Download Excel or CSV, add your cost code, cost type, and line item type columns, and paste into the SOV template Procore generates for the commitment, or pull JSON via the API and let your own integration post to purchase_order_contracts.
Yes. Purchase orders are one of the two commitment types in the project-level Commitments tool, alongside subcontracts. Procore defines a purchase order as a documented financial commitment detailing the types, quantities, and agreed-upon prices for products or services. You create one from the Contracts tab and give it a Schedule of Values for the line items.
Go to the project's Commitments tool, open the Contracts tab, click Create, and choose Purchase Order. Fill in contract number, contract company, and title, then the general information such as status, payment terms, ship to, and ship via. Add the line items on the Schedule of Values. The status has to reach Approved or Complete before you can raise change orders or invoices against it.
Only partly, and this is the detail that catches migrations out. Procore supports importing Schedule of Values line items into a commitment from CSV, but there is no native CSV or Excel import that creates the purchase order records themselves in bulk. Commitments are not in the Procore Imports desktop application either. Bulk creation goes through the REST API.
Purchase orders are purchase_order_contracts. List and create at /rest/v1.0/purchase_order_contracts, read, update, and delete at /rest/v1.0/purchase_order_contracts/{id}, and line items at /rest/v1.0/purchase_order_contracts/{id}/line_items. The PATCH sync variants handle batches. GET /rest/v1.0/commitments is read-only and returns purchase orders and subcontracts together, so it cannot be used to create either.
Procore documents that the sync endpoints accept attributes for a maximum of 1000 resources per call. Sync always returns HTTP 200 and reports per-record outcomes in an entities array and an errors array, so you have to read the response body rather than trust the status code. Rate limits apply on an hourly and a ten-second window, reported through the X-Rate-Limit headers.
Both are commitments, and in the API a subcontract is a work order contract. A purchase order carries assignee, bill to and ship to addresses, ship via, payment terms, and delivery date, and moves through Draft, Processing, Submitted, Partially Received, Received, Approved, and Closed. A subcontract carries contract dates, inclusions, and exclusions, and runs Draft, Out For Bid, Out For Signature, Approved, Complete, Terminated, and Void. Buy materials on a PO, buy labor and scope on a subcontract.
Rows are skipped when the cost code name, cost code number, line item type, or the amount is missing. A blank amount cell is rejected, so enter 0.00 rather than leaving it empty. Procore also requires that you do not add or move columns in its template, because the column order matches its database. And budget codes cannot be imported at all: supply cost code, cost type, and optional sub job instead.
By default, yes. With the Enable Always Editable Schedule of Values setting turned off, which is the default, the commitment must be in Draft to import line items. Turning that setting on allows the import at any status, but you still cannot replace line items that have already been invoiced.
Procore's ERP Integrations cover Viewpoint Spectrum, Vista, QuickBooks Desktop and Online, Sage 300 CRE, Sage 100 Contractor, Sage Intacct, Yardi Voyager, NetSuite, Acumatica, MRI Platform X, CMiC, Workday, and Xero. Procore states that each connector has its own feature set, so confirm commitment export on yours specifically. Foundation and Dynamics 365 Business Central are not on Procore's own supported list.
No, and we would rather say so plainly. It reads purchase order documents and returns structured data. It does not install in Procore, does not call purchase_order_contracts, does not write to Procore, and does not create, approve, receive, or match commitments. You keep using Procore's own SOV import or your own API integration; we just remove the typing in front of it.
Yes. The AI handles scans and phone photos, not only digital PDFs, and returns the same structured fields. That matters on construction projects because material orders and supplier confirmations often reach the office as a photo taken in a job trailer, which template-based OCR tools tend to miss or mangle.
Loading PO data into Vista through IM templates.
How Procore and Buildertrend handle purchase orders differently.
The construction use case end to end.
PO data for Sage Intacct.
PO data shaped for Acumatica.
The general ERP load path.
Extract PO data to JSON via REST API.
How the line-item table is captured.
Clear a migration backlog in batches.
See the output shape in Excel.