Creating Sales Orders in Acumatica via API
Acumatica's contract-based REST API provides a powerful way to create sales orders programmatically. Whether you're integrating an e-commerce platform, building a mobile app, or connecting to an external system, the API enables seamless order creation with full control over order details, line items, taxes, and allocations.
⚡ Key Insight: The SalesOrder entity is mapped to the Sales Orders (SO301000) form, and it supports both creation and update operations through the PUT method with the $expand parameter for including details[citation:2][citation:3].
Understanding the SalesOrder Entity
The SalesOrder entity is the primary endpoint for creating and managing sales orders via the Acumatica REST API. It corresponds to the Sales Orders (SO301000) form and supports a wide range of fields and nested objects[citation:2][citation:3].
The key components of a SalesOrder entity include:
- Order Header: Customer ID, Order Type, Description, Hold status
- Details: Line items with InventoryID, Quantity, Unit Price, and UOM
- Allocations: Lot/serial allocations for tracked inventory
- TaxDetails: Overridden tax information
Basic Sales Order Creation
To create a sales order, you send a PUT request to the SalesOrder endpoint. The system will create a new order if the key fields don't match an existing record[citation:2].
Request Example
PUT /entity/Default/24.200.001/SalesOrder?$expand=Details HTTP/1.1
Host: https://my.acumatica.com/MyInstance
Accept: application/json
Content-Type: application/json
{
"OrderType": { "value": "SO" },
"CustomerID": { "value": "GOODFOOD" },
"Description": { "value": "API Created Order" },
"Details": [
{
"Branch": { "value": "HEADOFFICE" },
"InventoryID": { "value": "APJAM08" },
"OrderQty": { "value": 2 },
"UnitOfMeasure": { "value": "PIECE" },
"WarehouseID": { "value": "WHOLESALE" }
}
]
}
💡 Pro Tip: Use "OrderNbr": { "value": "<NEW>" } to let the system automatically generate the order number[citation:11].
Creating Sales Orders with Allocations
For inventory items that use lot or serial tracking, you can specify allocations directly in the sales order creation request. This is particularly useful for tracking specific serial numbers or lot numbers[citation:5].
Request Example with Allocations
PUT /entity/Default/24.200.001/SalesOrder?$expand=Details,Details/Allocations HTTP/1.1
Host: https://my.acumatica.com/MyInstance
Accept: application/json
Content-Type: application/json
{
"CustomerID": { "value": "COFFEESHOP" },
"Description": { "value": "Sales Order with Allocations" },
"OrderType": { "value": "SO" },
"Hold": { "value": true },
"Details": [
{
"Branch": { "value": "HEADOFFICE" },
"InventoryID": { "value": "APJAM08" },
"LocationID": { "value": "MAIN" },
"Allocations": [
{
"InventoryID": { "value": "APJAM08" },
"LotSerialNbr": { "value": "116046" },
"Qty": { "value": 1 }
}
]
}
]
}
⚠️ Important: If you specify the Allocations/Qty field, do not specify the OrderQty field on the same line. Otherwise, empty allocations may appear in the created order[citation:5].
Creating Sales Orders with Tax Overrides
The API allows you to override tax calculations by specifying custom tax details. This is useful when the external system has already calculated taxes or when special tax rules apply[citation:8].
Request Example with Tax Override
PUT /entity/Default/25.200.001/SalesOrder?$expand=Details,TaxDetails HTTP/1.1
Host: https://my.acumatica.com/MyInstance
Accept: application/json
Content-Type: application/json
{
"CustomerID": { "value": "GOODFOOD" },
"IsTaxValid": { "value": true },
"Details": [
{
"Branch": { "value": "HEADOFFICE" },
"InventoryID": { "value": "APJAM08" },
"OrderQty": { "value": 2 },
"UnitOfMeasure": { "value": "PIECE" },
"WarehouseID": { "value": "WHOLESALE" }
}
],
"TaxDetails": [
{
"TaxID": { "value": "NYSTATETAX" },
"TaxableAmount": { "value": 0.5 }
}
]
}
Usage Notes for Tax Overrides
- If
IsTaxValidistrueand an external tax zone is specified, the tax details from the request are used without modification - If
IsTaxValidistrueand an internal tax zone is specified, the system compares the provided tax details with calculated ones - If
IsTaxValidis not specified, the system performs standard tax calculation[citation:8]
Creating Orders with Unit of Measure (UOM)
The API supports specifying custom units of measure for each line item. This is essential for businesses that sell products in multiple UOMs[citation:2].
{
"CustomerID": { "value": "GOODFOOD" },
"Details": [
{
"Branch": { "value": "HEADOFFICE" },
"InventoryID": { "value": "APJAM08" },
"OrderQty": { "value": 2 },
"UnitOfMeasure": { "value": "PIECE" },
"WarehouseID": { "value": "WHOLESALE" }
}
]
}
Creating Sales Orders from Opportunities
You can also create a sales order directly from an existing opportunity using a POST request to the Opportunity endpoint[citation:6].
POST /entity/Default/22.200.001/Opportunity/CreateOpportunitySalesOrder HTTP/1.1
Host: https://my.acumatica.com/MyInstance
Accept: application/json
Content-Type: application/json
{
"entity": {
"id": "f8e643f0-2110-e911-9fbe-7c5cf8918e20"
}
}
You can find the opportunity's id by querying the CROpportunity database table or by retrieving opportunities through the API[citation:6].
Converting Sales Quotes to Orders
If you're working with sales quotes, you can convert them to sales orders using a custom action in the API. This requires extending the default endpoint[citation:10].
Steps to Set Up Quote-to-Order Conversion
- Go to the Web Service Endpoints screen
- Select the Default Endpoint and click Extend Endpoint
- Add the Sales Quote screen to the new endpoint
- Add key fields:
OpportunityIDandQuoteNbr - Insert a new action called
createSalesOrder - Add
OrderTypeas a parameter[citation:10]
POST {baseUrl}/entity/{EndpointName}/{Version}/SalesQuote/createSalesOrder
{
"entity": {
"QuoteNbr": { "value": "YOURQUOTENBR" },
"OpportunityID": { "value": "YOUROpportunityID" }
},
"parameters": {
"OrderType": { "value": "SO" }
}
}
💡 Pro Tip: The request will only work if the Convert To Order button is enabled on the Sales Quote screen[citation:10].
Performance Best Practices
✅ Use $expand and $select
Request only the fields you need and use $expand to include details in a single request[citation:3].
✅ Batch Operations
Retrieve multiple records with multiple kinds of detail lines in one request for better performance[citation:3].
✅ Use Proper ReturnBehavior
Set ReturnBehavior = ReturnBehavior.OnlySpecified to limit fields returned[citation:7].
✅ Avoid Unnecessary Calls
Create orders with all necessary details in a single API call rather than multiple sequential calls.
Common API Endpoints Summary
| Operation | Method | Endpoint |
|---|---|---|
| Create Sales Order | PUT | /SalesOrder |
| Create Order from Opportunity | POST | /Opportunity/CreateOpportunitySalesOrder |
| Convert Quote to Order | POST | /SalesQuote/createSalesOrder |
| Retrieve Orders | GET | /SalesOrder?$filter=... |
Conclusion
The Acumatica contract-based REST API provides flexible, powerful capabilities for creating sales orders programmatically. Whether you're building a simple integration or a complex multi-system orchestration, the API supports:
- Basic order creation with customer and line item details
- Advanced features like allocations for lot/serial tracked items
- Tax override capabilities for external tax calculations
- Integration with opportunities and quotes
📌 Key Takeaway: The SalesOrder entity is your primary gateway for programmatic order management in Acumatica. By leveraging the PUT method with $expand parameters, you can create complex orders with all necessary details in a single API call.
🔍 Further Reading: Review the Acumatica Developer Network (ADN) for detailed endpoint documentation and additional examples. Consider extending the default endpoint when you need custom fields or actions in your API workflows.
🙏 Credits & Acknowledgments
Original Source: This article is based on the official Acumatica Integration Development Guide and community contributions.
📅 Reference materials: Integration Development Guide, 2024-2025