OCR Integration with Accounting Software, CRM and ERP: 5 Steps

Table of contents
To connect OCR to QuickBooks, Salesforce, SAP or an expense tool, use the same five steps: capture the document, extract fields, validate them, map them to the target's fields, then post and confirm. Most failures come from mapping and validation, not from reading the page.
OCR (optical character recognition) does not write to your books by itself. It reads a document and returns fields. Getting those fields into QuickBooks, Salesforce, SAP or an expense tool takes the same five steps every time: capture, extract, validate, map, and post and confirm. This page explains each step, gives field maps checked against each vendor's API docs, and links to our guide for each system.
How does OCR integration with accounting software work?
OCR integration with accounting software is a five-step pipeline: capture the file, extract fields, validate them, map them to the target system's fields, then post and confirm. The OCR only covers step 2. Steps 3 to 5 are code or configuration you own, and they decide whether data lands in the right fields.
- Capture. The file arrives by email, upload, scan or API. Keep the original to attach later. Our email invoice parsing guide covers intake traps.
- Extract. OCR returns fields as JSON (a plain-text data format): supplier, invoice number, dates, currency, lines, tax, total. It does not know your vendor list or chart of accounts.
- Validate. Check totals, duplicates, vendor match, tax and required fields before posting.
- Map. Turn each field into the target's field and ID: a vendor name becomes a vendor ID, and a category becomes a general ledger (GL) account. Data normalization cleans the inputs.
- Post and confirm. Call the API, read the response, store the returned ID, attach the source file, and send failures to a person.
Terms: an ERP is enterprise resource planning software (SAP, NetSuite). A CRM is customer relationship management software (Salesforce). A PO is a purchase order. An API is how programs talk to each other.
Which guide covers OCR integration with QuickBooks, Xero, NetSuite and SAP?
Use our four system guides: invoice OCR to QuickBooks, Xero, NetSuite and SAP. Each has its own field map and failure modes. Salesforce, other CRMs and expense tools are covered on this page, and the other guides below cover matching, exceptions, email intake and currency.
- Invoice OCR to QuickBooks sync: for OCR integration with QuickBooks, the Bill field map and five places the sync breaks.
- Invoice OCR to Xero: ACCPAY versus ACCREC, DRAFT versus AUTHORISED, and tracking categories.
- NetSuite invoice OCR: the vendorbill field map, item versus expense lines and OneWorld subsidiaries.
- Invoice OCR to SAP: for OCR integration with SAP, why PO and non-PO invoices post differently, and BAPI versus IDoc.
- OCR accounting: which accounting documents to automate first.
- Accounts payable OCR: the intake-to-routing pipeline and five vendor tests.
- 3-way match automation: how to tell a real mismatch from an OCR misread.
- Non-PO invoice exception routing: a true no-PO invoice versus a missed PO number.
- Email invoice parsing: forwarded threads, email-body invoices and sender checks.
- Multi-currency invoice OCR: picking the currency and the exchange rate to book.
What fields does each system expect?
Every system wants IDs, not names, plus a vendor, dates, lines and a total, but the field names differ. The tables below list them for QuickBooks, Xero, NetSuite, SAP and Salesforce, each checked against the vendor's API docs on September 21, 2026.
QuickBooks Online
Docs: Bill, Vendor, Attachable.
| Field | What to put in it, and what the docs say |
|---|---|
VendorRef (required) | The matched vendor's Id, not the name. |
Line (required) | Account-based line: Amount and AccountRef. Item-based line: ItemRef, Qty and UnitPrice. Your rules pick the account. |
TxnDate | Invoice date. The docs call it the posting date that affects the financial statements. |
DueDate | If omitted, SalesTermRef days are added to TxnDate. |
DocNumber | Supplier invoice number, 21 characters at most. A duplicate throws an error unless include=allowduplicatedocnum is set. |
TotalAmt | Read only. QuickBooks calculates it and overwrites what you send, so tie out totals yourself. |
CurrencyRef | Required when multicurrency is on. |
New vendor DisplayName | Up to 500 characters, unique across Vendor, Customer and Employee records. |
| Source file | A separate multipart upload to Attachable after the bill exists, up to 100 MB per request. |
Xero
Docs: Invoices. A supplier bill is an invoice of Type ACCPAY.
| Field | What to put in it, and what the docs say |
|---|---|
Type (required) | ACCPAY for a supplier bill. |
Contact (required) | Send only ContactID. Other fields update the contact record itself. |
LineItems (one or more) | Description, Quantity, UnitAmount, AccountCode, TaxType (overrides the account default) and Tracking (up to 2 per line). |
Date, DueDate | YYYY-MM-DD. Date defaults to today. |
InvoiceNumber | Supplier's number, 255 characters at most. Not unique for bills, so duplicate checks are yours. |
Status | DRAFT (the default; no journals; account codes may be missing), SUBMITTED (awaits approval) or AUTHORISED (creates journals). |
SubTotal, TotalTax, Total | Send all three on a SUBMITTED or AUTHORISED bill and Xero checks them against the lines, allowing a RoundingAmount up to 0.10 either way. The API spec calls this opt-in per organisation. |
| Source file | Up to 10 attachments, 25 MB each, after the invoice exists. |
NetSuite
Docs: REST API Browser, vendorBill (release 2025.2).
| Field | What to put in it, and what the docs say |
|---|---|
entity | The vendor, by internal ID. |
subsidiary | The legal entity billed. OneWorld needs your own rule to pick it. |
tranDate | The bill's posting date, which sets where it shows on the accounts payable register. |
dueDate | Without one, the docs say the bill is missing from aging reports. |
tranId | Reference No., suggested for the vendor's invoice number. |
expense lines | Account, amount, memo, department, class, location, taxAmount. |
item lines | Item, quantity, rate, amount, description, plus orderDoc and orderLine to point at a PO. |
currency, exchangeRate | The bill's currency and its rate. |
externalId | Your ID for the source document. A PUT to record/v1/vendorBill/eid:<ID> creates the bill or updates it, so retries do not duplicate. |
SAP
Docs: SAP Help Portal, Supplier Invoice OData service (S/4HANA Cloud). The BAPI column comes from secondary references, because SAP documents that function module inside its systems.
| Document data | OData field (mandatory, per SAP Help) | BAPI_INCOMINGINVOICE_CREATE |
|---|---|---|
| Company code | CompanyCode | COMP_CODE |
| Invoice date | DocumentDate | DOC_DATE |
| Posting date | PostingDate | PSTNG_DATE |
| Supplier's invoice number | SupplierInvoiceIDByInvcgParty | REF_DOC_NO |
| Supplier | InvoicingParty | Check the function module documentation |
| Currency | DocumentCurrency (items must match the header) | CURRENCY |
| Gross total | InvoiceGrossAmount (net items plus tax) | GROSS_AMOUNT |
| Line with a PO | PurchaseOrder, PurchaseOrderItem, SupplierInvoiceItem, TaxCode, SupplierInvoiceItemAmount | PO_NUMBER, PO_ITEM, INVOICE_DOC_ITEM, TAX_CODE, ITEM_AMOUNT |
| Line with no PO | G/L item: GLAccount, DebitCreditCode, SupplierInvoiceItemAmount | ACCOUNTINGDATA table |
Per SAP Help, the OData service is synchronous, needs a deep create (all nodes in one request), and can park or hold an invoice. An SAP Community answer says the BAPI needs BAPI_TRANSACTION_COMMIT to save.
Salesforce (an Opportunity with a file attached)
Docs: Opportunity, ContentVersion, ContentDocumentLink.
| Field | What to put in it, and what the docs say |
|---|---|
Opportunity.Name (required) | Deal or contract title, up to 120 characters. |
Opportunity.StageName (required) | A picklist value from your process, not the document. |
Opportunity.CloseDate (required) | Expected close date. |
Opportunity.Amount | Estimated total sale amount, such as contract value. |
Opportunity.AccountId | The matched Account, by ID. |
ContentVersion | Title, PathOnClient (full path with extension, needed for preview) and VersionData (base64, adding about 37% to size). The docs give 50 MB as the SOAP API upload limit. |
FirstPublishLocationId | Set to the Opportunity's ID to create the file and link it in one transaction. |
ContentDocumentLink | Links an existing file to more records, custom objects included. ShareType is required. |
What should you check before posting?
Check six things before any post: totals and line math, duplicates, vendor match, tax, dates and period, and required fields. If one fails, send the record to a person with the failing field highlighted. Xero, for example, refuses updates to bills in a locked period.
| Check | Rule | Why (from the docs) |
|---|---|---|
| Totals and line math | Quantity x unit price equals each line amount, and lines plus tax equal the total to the cent. | QuickBooks overwrites TotalAmt. SAP defines InvoiceGrossAmount as net items plus tax. Xero validates totals you send. |
| Duplicates | Same supplier and invoice number, then amount and date. See duplicate invoice detection. | Xero bills can repeat an invoice number. QuickBooks flags a duplicate DocNumber, which holds only 21 characters. |
| Vendor match | Resolve to the system's vendor ID. Never create a vendor without review. | QuickBooks needs a vendor Id, and a new DisplayName must be unique across vendors, customers and employees. |
| Tax | Each line has a tax code the target knows, and tax total equals line tax. | SAP PO lines require TaxCode. Xero TaxType overrides the account default. |
| Dates and period | Dates read as real dates, and the period is open. | QuickBooks TxnDate is the posting date. SAP keeps DocumentDate and PostingDate apart. |
| Required fields | Every mandatory field holds a real value, never a dummy one. | SAP's header has 7 mandatory fields. A Salesforce Opportunity needs Name, StageName and CloseDate. |
Worked example: two misreads the totals check catches
Take three lines: 12 x 24.50 = 294.00, 3 x 118.75 = 356.25, and freight of 45.00. The subtotal is 695.25. Tax at 8.25% on the two goods lines (650.25) is 53.6456, rounded to 53.65. The total is 748.90. We ran this in Python with the decimal module.
- OCR reads the total as 748.98. Lines plus tax give 748.90, so the check fails by 0.08.
- OCR reads the quantity 12 as 17. Then 17 x 24.50 = 416.50 against a printed 294.00, a gap of 122.50.
One trap: Xero allows a RoundingAmount up to 0.10 either way when you send totals. Use it only for rounding printed on the invoice, not to pass a misread like the 0.08 above.
This matters because OCR is never perfect. In our benchmark, the best result on invoice line items was 93%, so some lines will be wrong. In our 200-invoice AP trial, our own pipeline (DocsAPI, our product) reached 81% touchless with a validation layer we built, and about 65% before it. More in invoice line-item extraction.
What do you do when the ERP rejects a post?
Read the error, fix the mapped field and retry only that record. Most OCR integration for ERP systems fails in repeatable ways: duplicates, missing required fields, wrong IDs, rate limits and closed periods. Never retry blindly, because a timed-out post may have succeeded.
| System | What you see | Likely cause (per the docs) | What to do |
|---|---|---|---|
| QuickBooks | Error on DocNumber | The same DocNumber already exists | Look up that vendor's bill. Same invoice: log and skip. A different bill: retry with include=allowduplicatedocnum. |
| QuickBooks | HTTP 429 | Over 500 requests a minute or 10 a second per company | Wait 60 seconds, as the docs advise. Batch requests (30 payloads is the recommended maximum). |
| Xero | HTTP 400 with validation errors | A field fails validation, such as totals that do not tie | Post with SummarizeErrors=false so each invoice in a batch reports its own errors. Resend only the failures. |
| Xero | HTTP 429 | Over 60 calls a minute, or 5 at once, for one organisation | Pause that organisation until the Retry-After time. About 50 invoices per request is practical. |
| NetSuite | Timeout, unsure if it posted | The first call may have created the bill | Post with PUT to vendorBill/eid:<ID>. The same ID updates instead of duplicating. |
| SAP OData | Error messages in the response | A mandatory field is missing, or item currency differs from the header | Fix it and resend the whole deep create, because all nodes are created together. |
| SAP | Invoice posted but blocked | Price or quantity outside tolerance | The service can release a blocked invoice, but releasing is a buyer or AP decision. |
| Salesforce | HTTP 400, or 403 with REQUEST_LIMIT_EXCEEDED | 400: an error in the request body. 403 with that code: the org's API request limit | For 400, check required fields first. For 403, slow down, queue and retry later. |
Make posting safe to repeat. Log the source file, the payload and the returned ID for every attempt, and check that log before any retry.
How does OCR integration with CRM and Salesforce work?
OCR integration with CRM usually means reading a document, filling a few record fields, and attaching the file to the right record. Typical documents are business cards, contracts, order forms and ID copies. OCR with Salesforce integration follows the same pattern: fields go into an object such as Lead or Opportunity, and the file links through ContentVersion.
Salesforce has a native option. Salesforce Help describes an Intelligent Document Reader that uses Amazon Textract through your own AWS account and maps a form's fields to a Salesforce object's fields. The page we opened lists Health Cloud editions, so check yours. Otherwise, call an OCR API and write to Salesforce yourself, using the table above.
Business cards are the classic case. A Salesforce Lead needs Company and LastName, so a card with no company fails or gets a dummy value. Send those to review. HubSpot's contacts API needs at least one of email, firstname or lastname, treats email as the unique identifier, and has a batch upsert that creates or updates by email. One wrong character in an email creates a new contact, so a person should see emails.
For contracts and ID copies, attach the file to the Opportunity, Account or Contact and write only the few fields you use, such as contract value into Amount. The risk is attaching to the wrong record, so match by ID, not fuzzy name. Treat ID fields as claims, not proof (see know your customer documents). Loan teams feed a loan system instead: see OCR for loan underwriting.
How do you automate expense reports with OCR?
To automate expense reports with OCR, the employee photographs a receipt, OCR fills merchant, date and total, and the expense tool adds category, tax and policy checks before approval and posting. Microsoft's Dynamics 365 receipt OCR follows the same split: it extracts three fields, then matches receipts to expenses.
OCR for expense management is only the capture step. Microsoft Learn says its receipt OCR extracts merchant name, date and total amount. Category, tax, payment method and project come from the expense tool or the employee, and whether an expense is allowed is a policy call.
Two flows exist: receipt-first, where the employee creates an expense from a receipt, and card-feed-first, where card transactions are imported and receipts are matched to them. Microsoft's page describes matching unattached receipts to unattached expenses.
To reach the books, an approved expense becomes a transaction. In QuickBooks Online that is a Purchase, which requires Line, PaymentType (Cash, Check or CreditCard) and AccountRef (a bank or credit card account). Check for duplicates first: one expense can arrive twice, as a card transaction and as a receipt. Match on date, amount and merchant.
What is an OCR data entry automation tool?
An OCR data entry automation tool reads documents and fills fields that a person would otherwise type. Some are built into the system you already use, some are AP or expense platforms, and some are OCR APIs you connect yourself. OCR to automate data entry works best when every field has a validation rule and a review queue behind it.
| Type | Examples | Good when | Watch out for |
|---|---|---|---|
| Built into the target system | NetSuite Bill Capture, Dynamics 365 receipt capture, Salesforce Intelligent Document Reader | You use one system and want the fewest moving parts | Limits. Oracle says Bill Capture is US only, takes PDFs up to 30 pages, 8 MB per file, one bill per file, and a person clicks Create Bill. Dynamics reads three receipt fields. |
| AP or expense platform | Tools ranked in our AP tools trial | You want intake, approval and payment in one product | Which objects and fields it writes to your ERP. In our trial, no AP tool reached the 99% touchless rate vendors advertise. |
| OCR or document AI API | AWS Textract, Google Document AI, DocsAPI | You have developers, unusual documents or high volume | You write validation, mapping, posting and the exception queue. Costs: how invoice OCR pricing models compare. |
Ask any vendor: Which objects and fields do you write? Do you post as draft or final? What happens when a post is rejected? How do you avoid duplicates on retry? Is the original file attached to the record? Vendors who cannot answer sell extraction and leave the integration to you.
What to do next
- If you are still choosing a system, start with OCR for invoices and AP documents. If you already run one, open its guide above, build the field map for your chart of accounts, and run 20 real invoices from your messiest suppliers next to manual entry (parallel run sample size).
- If you are a developer starting from nothing, build steps 3 to 5 first with the checklist and error table. Any OCR API that returns JSON can feed them.
- If you need invoice fields as JSON, see our finance automation page. DocsAPI is our product. Its public manifest describes an HTTP API that returns JSON and lists no prebuilt connectors for QuickBooks, Xero, NetSuite, SAP or Salesforce, so plan to write or buy the mapping and posting code.
Sources and how we checked this
We opened each vendor's documentation on September 21, 2026 and checked every table field against it. Docs change, so recheck before you build. We did not run these calls against live sandboxes, so treat the tables as a starting point, not tested code.
- Intuit: Bill, Vendor, Attachable, Purchase, API limits.
- Xero: Invoices, API limits.
- NetSuite and Oracle: REST API Browser, Upsert Operation, Bill Capture limits, Uploading vendor bills.
- SAP: Supplier Invoice OData V2 and its header, PO item and G/L item pages. For the BAPI, an SAP Community answer and a copy of the function module documentation. The SAP Business Accelerator Hub needs a sign-in, so we did not use it.
- Salesforce: Lead, Intelligent Document Reader, REST status codes, plus the three objects linked above.
- HubSpot contacts API guide. Microsoft Capture a receipt using OCR.
- Ours: the OCR accuracy benchmark and the public DocsAPI manifest at docsapi.co/llms-full.txt.
Frequently asked questions
Not by itself. OCR returns fields, and a connector or your own code maps them and calls the target's API. Some products ship that layer, and some systems have built-in capture, such as NetSuite Bill Capture. DocsAPI's public manifest describes an HTTP API that returns JSON and does not list prebuilt connectors, so plan to build or buy the posting step.
Start with drafts or a review step. Xero accepts DRAFT, SUBMITTED or AUTHORISED, and only AUTHORISED creates journals. NetSuite Bill Capture asks a person to click Create Bill after reviewing suggestions. SAP's service can park or hold an invoice. Move to automatic posting only for suppliers whose parallel-run results were clean.
Use the target's safe-retry option where one exists: a NetSuite PUT to an external ID creates or updates, so a retry does not create a second bill. In QuickBooks, look up the vendor's bill by DocNumber before retrying. In Xero, bills can repeat invoice numbers, so check supplier plus invoice number yourself. Store the returned ID for every post.
No. OCR reads text and knows nothing about your books. QuickBooks needs an AccountRef, Xero an AccountCode and SAP a GLAccount for lines without a PO. Those come from vendor-to-account rules or a person. Send suppliers you have never coded before to a review queue instead of guessing.
Attach it in a separate step after the record exists. QuickBooks takes a multipart upload to Attachable with the bill's Id, up to 100 MB per request. Xero allows up to 10 attachments per invoice, 25 MB each. In Salesforce, create a ContentVersion with FirstPublishLocationId set to the record's ID. Without this, an auditor has no source document.
Yes, through the API. A contact needs at least one of email, firstname or lastname, and HubSpot treats email as the primary unique identifier. A batch upsert endpoint creates or updates contacts by email, so a re-scanned card updates the contact instead of duplicating it. Have a person check email addresses, because one wrong character creates a new contact.
No. Microsoft's Dynamics 365 receipt OCR page lists the USA, Canada, the UK and Australia as supported, the EU partly (English receipts only), and Asia, Japan and Africa as not supported. It also says support is not expanding. Test your countries, languages and receipt types before you commit to a tool.
Oracle's docs say it is available only in the United States and accepts PDF, JPEG and PNG. PDFs can run to 30 pages, images to 1 page, each file up to 8 MB, one bill per file, and up to 50 files per upload. A person reviews the suggestions and clicks Create Bill. Bills without a PO have a few unsupported features.
Not for most invoice streams. In our benchmark of 8 AP tools on 200 real invoices, none reached the 99% touchless rate vendors advertise, and the realistic ceiling was in the low 80s. Our own pipeline scored 81% with a validation layer we built and about 65% without it. Keep a review queue for the rest.
Its public manifest describes an HTTP API that returns extracted fields as JSON, with classification and validation, and it is cloud-only. The manifest does not list prebuilt connectors for QuickBooks, Xero, NetSuite, SAP or Salesforce, so the mapping and posting code is yours or a partner's. This page states only what the manifest says.
Related Blog Posts

Credit Card Statement OCR, Honest Setup Guide
I once had to reconcile 400 expense reports against credit card statements by hand. Two weeks I will never get back. Here is how to never let that happen to anyone again.

Invoice OCR to QuickBooks Sync: What Actually Breaks
We mapped OCR-extracted invoice fields to the real QuickBooks Bill object and found five places the sync silently breaks. The field map and the fixes.

NetSuite Invoice OCR: What Bill Capture Actually Misses
NetSuite Bill Capture is built in. It fills the header and suggests line items, but a person verifies every bill. The vendorbill field map and where automation breaks.
Want to see it on your own documents?
Try our free OCR tool in your browser, or book a demo to see how DocsAPI reads the document types covered in this guide.
