Guide ยท Sage 100 BOI
The Sage 100 Business Object Interface (BOI): what it is and when you need it
Short answer: BOI is the COM interface to the same business objects the Sage 100 desktop screens use. It is the sanctioned way to write to Sage 100: create sales orders, customers or invoices with Sage's own validation, numbering, pricing and tax. It is included with Sage 100 from version 4.3. It runs only on Windows, on a machine with the Sage 100 workstation software installed.
ODBC or BOI?
| You need to | Use | Why |
|---|---|---|
| Read lists for reports, BI or a sync | ODBC | Plain SQL, fast on key columns, any language. |
| Create or change orders, customers, items | BOI | The ODBC driver is read-only. BOI runs Sage's validation and defaults, so the record looks as if a user entered it. |
| Import a batch file every night | Visual Integrator | A Sage module for scheduled imports and exports, configured inside Sage 100; separately licensed. |
| Call Sage 100 over HTTP | Nothing built in | sData was removed in version 2025. You need a program next to Sage 100 that exposes BOI or ODBC over HTTP. |
Writing directly to the data files, or to the SQL tables on Premium, skips the business logic and is not supported by Sage.
What BOI requires
- Windows with the Sage 100 workstation installed. The COM entry point is
ProvideX.Script. IfNewObjectfails with error 200, the BOI components are usually not registered on that machine; run the Sage 100 workstation setup there. - Matching bitness. Your process must match the installed Sage 100 components. Sage 100 2026 is 64-bit only.
- A Sage 100 user whose role allows the tasks you call. Plan for a connected BOI session to take a user license seat; older community answers say so, confirm it on your version.
- Documentation lives in the "File Layouts and Program Information" section of Sage 100 help. It lists every business object, its fields and their types. Sage support does not debug BOI programs, so budget for your own testing.
The sequence every BOI program follows
- Create
ProvideX.Scriptand callInitwith the path toMAS90\Home. - Create the session:
NewObject("SY_Session"), thennSetUser,nSetCompany,nSetDateandnSetModule. - Tell the session which task you run:
nSetProgram(nLookupTask("SO_SalesOrder_ui")). The security check uses this task. - Create the business object with the session:
NewObject("SO_SalesOrder_bus", session). - Set the key, set values, write. Methods starting with
nreturn a number: 1 is success, 0 is failure. After a failure, readsLastErrorMsgon the same object. - Drop the objects and the session when you finish, or the license seat stays taken.
Example: create a sales order from Python
This follows the VBScript and C# pattern from the Sage community and Stack Overflow answers listed below, written for Python with pywin32. Test it against a copy of the company before you point it at live data.
import win32com.client
HOME = r"C:\Sage\Sage 100 Standard\MAS90\Home"
px = win32com.client.Dispatch("ProvideX.Script")
px.Init(HOME)
ss = px.NewObject("SY_Session")
def ok(ret, obj):
if ret != 1:
raise RuntimeError(obj.sLastErrorMsg)
ok(ss.nSetUser("APIUSER", "secret"), ss)
ok(ss.nSetCompany("ABC"), ss)
ok(ss.nSetDate("S/O", "09272026"), ss) # MMDDYYYY
ok(ss.nSetModule("S/O"), ss)
ok(ss.nSetProgram(ss.nLookupTask("SO_SalesOrder_ui")), ss)
so = px.NewObject("SO_SalesOrder_bus", ss)
try:
ok(so.nSetKeyValue("SalesOrderNo$", "0001043"), so)
ok(so.nSetKey(), so)
ok(so.nSetValue("ARDivisionNo$", "01"), so)
ok(so.nSetValue("CustomerNo$", "AVNET"), so)
ok(so.nSetValue("CustomerPONo$", "SHOP-5512"), so)
lines = so.oLines
ok(lines.nAddLine(), lines)
ok(lines.nSetValue("ItemCode$", "1001-HON-H252"), lines)
ok(lines.nSetValue("QuantityOrdered", 4), lines)
ok(lines.nWrite(), lines)
ok(so.nWrite(), so)
finally:
so.DropObject()
ss.nCleanup()
ss.DropObject()
- String fields take a
$suffix innSetValue("CustomerNo$"); numeric fields do not ("QuantityOrdered"). - Write the lines, then the header. Nothing is saved until the header
nWritesucceeds. - Check
sLastErrorMsgon the object that failed. A line error is onoLines, not on the header. - Use your own reference, such as the web order number in
CustomerPONo, to find an order again if your program stops between the write and its log entry. That prevents duplicate orders on retry.
Sources: Sage 100 help: BOI FAQs, Sage community: sales order code, Stack Overflow: BOI from C# and error 200, Stack Overflow: where BOI is documented.
Hundred is a planned REST API for Sage 100 that will run BOI for you, with retries, idempotency and error mapping. Early access, rolling out in stages.
Join early access