Guide ยท Sage 100 and EDI
Sage 100 EDI: mapping X12 850, 856 and 810 to sales orders, shipments and invoices
Short answer: an inbound 850 purchase order becomes a Sage 100 sales order: the PO number goes into CustomerPONo, the routing into ShipVia, and each PO1 line into a line with ItemCode, QuantityOrdered and UnitPrice. The outbound 856 ship notice and 810 invoice are read back from Sage 100's S/O invoice tables, where Shipping Data Entry records shipped quantities, packages and tracking numbers, and from invoice history once the invoice is posted. Translating X12, holding the trading partner maps and sending the files is the job of an EDI translator or service. This guide maps the fields on the Sage 100 side.
Who does what in a Sage 100 EDI setup
| Piece | What it does | Examples |
|---|---|---|
| Trading partner | Sends 850 purchase orders; expects 856 ship notices and 810 invoices back, as its implementation guide specifies. | Your retail or manufacturing customers. |
| Network (VAN, AS2, SFTP) | Carries the X12 files between you and the partner. | Often included in an EDI service. |
| EDI translator | Turns X12 into records your system understands and back, per partner map; validates and acknowledges (997). | Sold as a service or run in-house. |
| The Sage 100 side | Creates the sales order; records shipment and invoice so the translator can read them. | Embedded in the EDI product, a custom service using the Business Object Interface (BOI), or file imports. |
Where Hundred fits: Hundred is a planned REST API for the Sage 100 side of that chain. It is not an EDI translator, a VAN or an AS2 service: it will not read or write X12, hold partner maps or connect to your trading partners. It is meant to work alongside one, for a translator or an in-house EDI system that would rather call one HTTPS endpoint than build and maintain its own component for Sage 100. A small Hundred connector would still run on the Sage 100 server. It is not built yet; nothing below is callable today.
850 purchase order to a Sage 100 sales order
A trimmed 850 (envelope segments left out) and the sales order it should become. Item and order numbers match the sales order example in Hundred's planned API reference.
Inbound 850 (excerpt)
BEG*00*SA*5512**20260927~ N1*ST*DC 14*92*0014~ TD5*****UPS GROUND~ PO1*1*4*EA*129.50**VP*1001-HON-H252~ PO1*2*1*EA*19.95**VP*6655~ CTT*2~
Planned POST /sales-orders body
{
"customerId": "01-AVNET",
"customerPoNo": "5512",
"shipVia": "UPS GROUND",
"lines": [
{ "itemCode": "1001-HON-H252",
"quantityOrdered": 4,
"unitPrice": 129.50 },
{ "itemCode": "6655",
"quantityOrdered": 1,
"unitPrice": 19.95 }
]
}| X12 850 | Sage 100 field | Planned Hundred field | Watch out for |
|---|---|---|---|
BEG03 purchase order number | SO_SalesOrderHeader.CustomerPONo (30 characters) | customerPoNo | Look it up before you create the order. If an order with that PO number exists for that customer, the 850 already went in. With the planned API, also send it as the Idempotency-Key. |
BEG05 purchase order date | No PO date field among the header fields above; Sage sets OrderDate | Not in the published request | Keep it in the translator; the 810 needs it back in BIG03. |
N1*BY or N1*BT plus the sender ID | ARDivisionNo + CustomerNo | customerId (01-AVNET) | X12 does not carry your customer number. Keep a table: partner ID to Sage customer. |
N1*ST with N3/N4 | ShipToCode (4 characters), or ShipToName, ShipToAddress1, ShipToCity, ShipToState, ShipToZipCode | Not in the published request yet | Store the partner's store or DC number (N104) as a ship-to code if the partner reuses its locations. |
TD5 element 05, routing | ShipVia (15 characters) | shipVia | Free text in X12, a code in Sage 100. Map the partner's wording to one of your ship-via codes. |
DTM*002 delivery requested, DTM*010 requested ship, DTM*038 ship no later | ShipExpireDate on the header, PromiseDate on lines | Not in the published request yet | Agree with the partner which date counts as the ship date. |
PO102 quantity | SO_SalesOrderDetail.QuantityOrdered | lines[].quantityOrdered | Read it together with the unit of measure. |
PO103 unit of measure (EA, CA) | UnitOfMeasure (4 characters) | Not in the published request yet | X12 codes are not Sage codes. A partner ordering in cases (CA) while you sell in each needs a conversion. |
PO104 unit price | UnitPrice | lines[].unitPrice | Decide who wins on price. Leave it out to let Sage 100 price the line; send it to take the partner's price. |
PO106/PO107 product ID: VP or VN (your part number) | ItemCode (30 characters) | lines[].itemCode | Matches directly when the partner sends your number. |
PO106/PO107: BP or IN (buyer's number), UP (GTIN-12) | AliasItemNo on the line can hold the buyer's number; ItemCode still needs your number | Translate to itemCode first | Keep a cross-reference of buyer numbers and GTINs to your item codes, and reject the order if a line does not resolve. |
CTT01 number of line items | None | None | Check it against the lines you created, then send the 997. |
Create the order through Sage 100's Sales Order business object, not by writing tables, so pricing, tax, credit checks and numbering run as they do for your staff. The BOI guide shows how.
This 850 is your customer's purchase order to you. Purchase orders you send to your own vendors, and the receipts of goods when they arrive, are Sage 100's Purchase Order module: Guide 08 covers them, with stock per warehouse.
856 ship notice: where the data lives in Sage 100
In Sage 100 a shipment is recorded against an S/O invoice. Shipping Data Entry, available when Enable Shipping is selected in Sales Order Options, takes the shipped quantities, freight and weight, and a Tracking button for tracking numbers. Those land in the unposted invoice tables. After the invoice is posted, the same data is in invoice history. An 856 announces a shipment before it arrives, so it is usually sent when the goods leave: read the unposted tables.
| X12 856 | Before posting (S/O invoice) | After posting (AR history) |
|---|---|---|
BSN02 shipment identification | SO_InvoiceHeader.InvoiceNo (a common choice, not a rule) | AR_InvoiceHistoryHeader.InvoiceNo + HeaderSeqNo |
BSN03 date; DTM*011 shipped | ShipDate | ShipDate |
TD5 carrier and routing | ShipVia | ShipVia |
TD1 packages and weight | NumberofPackages, Weight | NumberOfPackages, Weight |
REF*2I tracking number (or REF*CN carrier reference) | SO_InvoiceTracking.TrackingID, one row per PackageNo | AR_InvoiceHistoryTracking.TrackingID |
PRF01 purchase order number | CustomerPONo | CustomerPONo |
LIN item identification | SO_InvoiceDetail.ItemCode, AliasItemNo | AR_InvoiceHistoryDetail.ItemCode, AliasItemNo |
SN102 units shipped | QuantityShipped (compare with QuantityOrdered for back orders) | QuantityShipped |
MAN carton marks (label numbers) | The tables above store label counts, not the label numbers themselves. Those come from your label or packing system. | |
The tracking table has one row per package (InvoiceNo + PackageNo), but the invoice lines carry no package number in the fields above. If a partner wants a pack-level 856 (which item is in which carton), find out where your setup or EDI product stores that before you promise it.
Hundred: a shipments endpoint for this data is planned but not designed yet, so it is not in the API reference. The planned invoice endpoints read posted invoices only, which is too late for most ship notices.
810 invoice: where the data lives in Sage 100
Read the 810 from the same invoice: before posting from SO_InvoiceHeader and SO_InvoiceDetail, after posting from AR_InvoiceHistoryHeader and AR_InvoiceHistoryDetail.
| X12 810 | Sage 100 field | Watch out for |
|---|---|---|
BIG01 invoice date, BIG02 invoice number | InvoiceDate, InvoiceNo | In history, InvoiceNo plus HeaderSeqNo is the key. |
BIG04 purchase order number | CustomerPONo | BIG03, the PO date, comes from the translator (see the 850 table). |
ITD terms of sale | TermsCode, InvoiceDueDate | Sage stores a 2-character code; the partner wants days and percentages. Map each terms code once. |
IT102 quantity invoiced | QuantityShipped | Invoice what shipped, not what was ordered. |
IT103 unit, IT104 unit price | UnitOfMeasure, UnitPrice | Convert back to the unit the partner ordered in. |
IT106/IT107 product ID | ItemCode, or AliasItemNo for the buyer's number | Send the same qualifier the 850 used. |
SAC charges, such as freight | FreightAmt | Partners differ on whether freight is a SAC charge or a line. |
CAD carrier details | ShipVia, plus TrackingID from the tracking table | |
TDS01 total amount | The invoice total, including SalesTaxAmt and FreightAmt | X12 sends it with two implied decimals: 2140.00 is sent as 214000. |
Hundred: the planned GET /invoices reads posted invoices from invoice history, with invoiceNo, invoiceDate, customerId, salesOrderNo, invoiceTotal and dueDate; GET /invoices/{invoiceNo} adds the lines. Unposted invoices are not in the plan for launch, so with Hundred an 810 would go out after posting.
EDI providers that integrate with Sage 100
If you want one product to do the translation, the partner maps and the Sage 100 side, these providers describe a Sage 100 integration on their own pages. They are examples, not a complete list; Hundred has not tested them and does not endorse them.
- SPS Commerce: Fulfillment for Sage 100, built on Mapadoc, which SPS describes as "fully embedded within Sage 100cloud", for orders, invoices and ship notices. SPS Commerce: Sage 100.
- TrueCommerce: its Sage 100 integration creates Sales Order Entries from inbound 850s and reads Invoice Data Entry and Shipping Data Entry to generate 810s and 856s; the product page says it uses "the native Sage Business Objects interface". Integration overview, creating ship notices, product page.
- EDIconnect: lists X12 850, 855, 856, 810, 820 and 997, and says it connects Sage 200 and Sage 100 through "standard ODBC/Web API". EDIconnect: EDI for Sage.
If one of these already covers your partners, you do not need a separate API for EDI. A REST API on the Sage 100 side matters when the translator is yours, or runs in the cloud, and you would rather not build and maintain your own Sage 100 component.
Before you build
- Start from the partner's implementation guide. Each trading partner publishes which segments and codes it requires. Where it differs from this page, the partner's guide wins.
- Build the cross-references first: partner ID to customer, ship-to locations, buyer part numbers and GTINs to item codes, X12 units to Sage units, routing text to ship-via codes, terms codes to
ITDvalues. - Make the 850 import safe to repeat: check
CustomerPONoper customer before you create an order, and log the PO number next to the Sage order number. - Turn on Enable Shipping if you need 856s with tracking numbers, and make sure tracking numbers are entered or imported from your carrier system.
- Check the version. Sage 100 2026 is 64-bit only; any EDI component on the Sage 100 server must be 64-bit (see the 64-bit guide).
Sources: Sage 100 file layouts for SO_SalesOrderHeader, SO_SalesOrderDetail, SO_InvoiceHeader, SO_InvoiceDetail, SO_InvoiceTracking, AR_InvoiceHistoryHeader, AR_InvoiceHistoryDetail and AR_InvoiceHistoryTracking; Sage 100 help, Enter Shipping Freight/Weight; Stedi's X12 reference for the 850, 856 and 810, and the product ID qualifiers.
Running your own EDI translator and need the Sage 100 side? Hundred is a planned REST API for Sage 100: your translator would call one HTTPS endpoint to create sales orders and read invoices, and a small connector on the Sage 100 server would carry each call in. It is not built yet. Early access, rolling out in stages.
Join early access