Systems
Sage Intacct integration with your online store, on the REST API
Sage Intacct sells API capacity in performance tiers: Tier 1 allows 100,000 API transactions a month and 6 concurrent requests per application. We build the integration to your tier, your transaction definitions and your dimensions, then host and run it.
What Sage Intacct is and who runs it
Sage Intacct is the cloud financial system of the Sage Group: general ledger, accounts payable and receivable, cash management, and modules for order entry, purchasing and inventory control. Sage ships its releases quarterly. It is built for companies with more than one entity: a request runs at the top level of the company or for one entity in it,.
Two things set it apart for an integration. First, dimensions: location, department, class, customer, item and others are tagged on every transaction line, and reports are built on them. A store order that arrives without the right dimensions posts correctly and still breaks the reports. Second, documents are defined per company. A sales order in Order Entry is a document of the transaction definition called "Sales Order" in that company, and its name, numbering and posting are configured by whoever set up the account.
What connects to Sage Intacct
| Flow | Direction | REST object |
|---|---|---|
| Orders | store to Sage Intacct | order-entry/document::Sales Order with lines |
| Customers | store to Sage Intacct | accounts-receivable/customer |
| Invoices and payments | both ways | accounts-receivable/invoice, accounts-receivable/payment |
| Items | Sage Intacct to store | inventory-control/item |
| Stock per warehouse | Sage Intacct to store | inventory-control/item-warehouse-available-inventory |
| Price lists | Sage Intacct to store | order-entry/price-list, order-entry/price-list-entry |
| Shipping status | Sage Intacct to store | trackingNumber and shippedDate on the document |
Companies that use Sage Intacct only for financials, without Order Entry and Inventory Control, get the store's sales as AR invoices and payments instead of orders. Which of the two applies is the first question for any e-commerce ERP integration on Intacct.
An order goes in with its lines in one request to the document endpoint. The lines are owned objects of the document, so Sage Intacct creates them in the same transaction:
POST /ia/api/v1/objects/order-entry/document::Sales%20Order HTTP/1.1
Host: api.intacct.com
Authorization: Bearer eyJhbGciOi...
Content-Type: application/json
{
"customer": { "id": "C10432" },
"txnDate": "2026-10-03",
"referenceNumber": "SHOP-100482",
"lines": [{
"dimensions": {
"item": { "id": "KB-2210" },
"warehouse": { "id": "MAIN" },
"location": { "id": "100" }
},
"unit": "Each", "unitQuantity": "12", "unitPrice": "17.08"
}]
}
The store order number goes in referenceNumber; customerPONumber is kept for a B2B buyer's purchase order. Before each retry the integration queries on the reference number, so a timeout never produces a second order. The order fields per flow are on order integration.
How Sage Intacct exposes data
REST API and XML API
| Item | REST API | XML API |
|---|---|---|
| Endpoint | api.intacct.com/ia/api/v1/objects/... |
api.intacct.com/ia/xml/xmlgw.phtml |
| Format | JSON | XML only |
| Authentication | OAuth 2.0, bearer token | sender ID plus session ID |
| Reads | query service, up to 4,000 records per response | queries, Sage advises fewer than 1,000 records per page |
| Writes | single record, or batches of up to 500 | functions in a request, optionally as one transaction |
Both need a Web Services developer subscription and a sender ID that the company administrator has authorized. New integrations go on REST. Sage versions it in the path: a breaking change produces a new version, released only with a quarterly release, and the previous version stays available for two years. Version 1-beta2 was deprecated on 10 December 2025. The rate and concurrency page has the tier table below.
OAuth 2.0 with a Web Services user
Sage Intacct supports the authorization code grant and the client credentials grant. An unattended integration uses client credentials: the application is tied to a Web Services user, a user without UI access, and requests a token for userId@companyId, or userId@companyId|entityId for one entity of a multi-entity company. The token response shows expires_in: 43200, twelve hours. Several tokens can be active for the same user at once, but revoking one revokes all of them, so a second integration on the same Web Services user shares that risk. Each integration gets its own user.
Performance tiers
| Tier | API transactions a month | Concurrency (application/company) |
|---|---|---|
| Tier 1 | 100,000 | 6/8 |
| Tier 2 | 250,000 | 8/10 |
| Tier 2-500k | 500,000 | 8/10 |
| Tier 3 | 1,000,000 | 12/15 |
| Tier 4 | 2,500,000 | 15/20 |
A transaction is one record created, updated or deleted, or one query. Transactions above the monthly entitlement are not blocked; Sage charges an overage fee. Transactions of authorized Marketplace partners do not count against the customer's tier. Concurrency is enforced: a request over the limit gets HTTP 429 with gateway code GW-0010, "API rate limit exceeded".
The arithmetic for 600 orders a day on Tier 1: 600 order documents, 600 customer queries before each order, and a stock query every 15 minutes, which is 96 a day. That is 1,296 transactions a day and 38,880 in a 30-day month, inside the 100,000. The same stock read done as one request per item for 15,000 items would cost 15,000 transactions per run instead of 4 queries of 4,000 rows. Read in bulk, write per record, and the tier stops being the bottleneck. The general calculation is on integration throughput.
Where a Sage Intacct integration gets stuck
Dimensions the store does not have. Item, warehouse and location travel inside dimensions on each line, next to department, class and any custom dimension the company uses. The store knows none of them except the item. The integration fills them by rule, for example location from the store or the warehouse and department from the sales channel, and a missing rule puts the order on the exception list instead of letting it fail with a 422.
Transaction definitions with your names. The endpoint carries the definition name: document::Sales Order, document::Sales Invoice, or whatever the company called it. Conversions follow the definition's workflow: a Sales Order is converted into a Sales Invoice by posting a new document with sourceDocument pointing at the order. When someone renames a definition, every call to the old name fails, so the integration reads the definitions at start-up and stops with a clear message.
Three stock numbers per warehouse. item-warehouse-available-inventory returns quantityLeft (received minus shipped), quantityAllocated (picked for specific orders) and quantityReserved (on the shelf but held). The store gets left minus both. With lot or serial tracking the same item has a row per lot, and the integration adds them up per warehouse. See which stock counts and multi-location inventory.
Batch errors that are partial. A batch of up to 500 records returns 207 Multi-Status with a status per record, so 497 can succeed and 3 fail. With the X-IA-API-Param-Transaction header set, the whole batch is atomic and one error rolls everything back. We use atomic batches for records that belong together and per-record status for independent ones, and every failed record gets its own retry.
Platforms we integrate with Sage Intacct
The store side is described per platform on Shopify, BigCommerce and WooCommerce. EDI with retailers is on Sage EDI integration. Other ERPs: NetSuite and Acumatica.
We build the integration to your tier, your transaction definitions and your dimensions, then host, run and monitor it for a monthly fee. Before go-live it runs as a dry run that writes nothing to Sage Intacct, so your controller sees every document and dimension it would post. All integrations come with a dashboard, logs and a per-run diff. Tell us how your Sage Intacct is set up.
Frequently asked questions
Which performance tier does a store integration need?
That follows from your transaction count. Sage Intacct counts each record created, updated or deleted as one transaction, and each query as one, however many rows it returns. A store with 600 orders a day usually stays well inside the 100,000 transactions a month of Tier 1. Going over the entitlement is not blocked; Sage charges an overage fee for the transactions above it.
What happens when the integration hits the concurrency limit?
The REST API answers HTTP 429 with the gateway code GW-0010, "API rate limit exceeded". Our integrations keep their own queue, run with fewer parallel requests than the application limit of the tier, and retry a 429 after a pause, so an order waits instead of failing.
Should a new integration use the XML API or the REST API?
The REST API. It takes JSON, authenticates with OAuth 2.0 and follows a published versioning policy: a previous version stays available for two years after a new one. The XML API on xmlgw.phtml accepts XML only and authenticates with a sender ID and a session. Both need a Web Services developer subscription and a sender ID that the company has authorized.
Can Sage Intacct push changes to the integration?
Yes. A Platform trigger of type HTTP post with webhook delivery sends the event to an endpoint. If the call fails, Sage Intacct retries up to 4 attempts in total, after 10, 30 and 90 seconds, for errors such as 429, 500 and 503. We use the webhook as a signal and run a reconciliation pass next to it. See why webhooks are not a guarantee.
Our company has several entities. Does that change the integration?
Yes. A request runs at the top level unless it names an entity, either in the token request as userId@companyId|entityId or in the X-IA-API-Param-Entity header. The integration writes each store order to the entity that sells it, with the location, department and other dimensions your reports expect.
Tell us what you need
Tell us which systems you use and what needs to work better. We reply personally within one working day. We help you define the work, then agree the price and timing before you commit.
- You know the price and the timeline before you commit to anything
- We work out the connection that takes the work off your hands
- We handle the build, hosting, monitoring and maintenance
- Your team has less information to retype and fewer discrepancies to chase