Microsoft Business Central API
This guide explains how to use API to establish a direct, secure connection to SOLSOL Microsoft Dynamics 365 Business Central, allowing authorized 3rd parties to read master data for products in SOLSOL portfolio, including pricing, stock availability, and technical specifications.
Gemini said
Fair Usage & Access Policy
To ensure the performance, security, and availability of the SOLSOL Dynamics 365 API for all users, we implement a Fair Usage Policy. By using this API, you agree to the following terms:
1. Rate Limiting & Resource Usage
The API is intended for efficient data synchronization. Users are expected to optimize their requests by using OData filters (e.g., ?$filter=...) to minimize server load.
-
Excessive Polling: Repetitive, high-frequency "polling" for data that has not changed is discouraged.
-
Throttling: We reserve the right to throttle or temporarily limit requests from any Client ID that consistently exceeds reasonable volume thresholds or impacts the performance of the Business Central environment.
2. Security & Unauthorized Access
Data integrity and privacy are our highest priorities.
-
Scope of Access: You may only access endpoints and data fields explicitly granted to your API credentials.
-
Prohibited Actions: Any attempt to bypass security layers, perform "brute force" discovery of undocumented endpoints, or extract data outside of your authorized scope is strictly prohibited.
3. Right to Revoke Access
SOLSOL reserves the right to immediately suspend or permanently revoke API access (including Client IDs and Secrets) without prior notice for any entity found to be:
-
Engaging in malicious activity or "stress-testing" the production environment.
-
Attempting to access unauthorized datasets.
-
Sharing API credentials with unauthorized third parties.
-
Violating the technical guidelines outlined in this documentation.
Authentication
Access is managed via OAuth 2.0 Client Credentials Flow. You must request a Bearer Token before making any data calls.
1. Token Request
Method: POST
Request URL: https://login.microsoftonline.com/d18c2b33-dc88-4c06-b71c-67a7ba3d83fe/oauth2/v2.0/token
Request Body Parameters:
- client_id
Provided upon request - grant_type
client_credentials - client_secret
Provided upon request - scope
https://api.businesscentral.dynamics.com/.default
Note: The token is valid for 3600 seconds (1 hour). We recommend caching the token and only refreshing it upon expiration or a 401 Unauthorized response.
Example of valid response (200 OK):
{ "token_type": "Bearer",
"expires_in": 3599,
"ext_expires_in": 3599,
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IlBjWDk4R1g0MjBUMVg2c0JEa3poUW1xZ3dNVSIsImtpZCI6IlBjWDk4R1g0MjBUMVg2c0JEa3poUW1xZ3dNVSJ9.eyJhdWQiOiJodHRwczovL2FwaS5idXNpbmVzc2NlbnRyYWwuZHluYW1pY3MuY29tIiwiaXNzIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvZDE4YzJiMzMtZGM4OC00YzA2LWI3MWMtNjdhN2JhM2Q4M2ZlLyIsImlhdCI6MTc2ODk5NDM2NywibmJmIjoxNzY4OTk0MzY3LCJleHAiOjE3Njg5OTgyNjcsImFpbyI6ImsyWmdZSGoza0hsTG12Z2xpNFdpZkI4T1RIMFhCUUE9IiwiYXBwaWQiOiIzYTMwOWE2NS00NmEwLTQ2YjUtODRiNy1hYmExMjI0YjRiMjgiLCJhcHBpZGFjciI6IjEiLCJpZHAiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC9kMThjMmIzMy1kYzg4LTRjMDYtYjcxYy02N2E3YmEzZDgzZmUvIiwiaWR0eXAiOiJhcHAiLCJvaWQiOiIyYmUwYzk2Mi02MWU3LTRlMTYtYWI0MS1jMGM3YTZlMmI1OTkiLCJyaCI6IjEuQVJBQU15dU0wWWpjQmt5M0hHZW51ajJEX2ozdmJabHNzMU5CaGdlbV9Ud0J1SjlMQVFBUUFBLiIsInJvbGVzIjpbIkFQSS5SZWFkV3JpdGUuQWxsIl0sInN1YiI6IjJiZTBjOTYyLTYxZTctNGUxNi1hYjQxLWMwYzdhNmUyYjU5OSIsInRpZCI6ImQxOGMyYjMzLWRjODgtNGMwNi1iNzFjLTY3YTdiYTNkODNmZSIsInV0aSI6InZqdy01RkhjYVVxNUV3UlloM2gwQUEiLCJ2ZXIiOiIxLjAiLCJ4bXNfYWN0X2ZjdCI6IjkgMyIsInhtc19mdGQiOiJLWW9BUXlmTzBHaGp5d3N5bmRjb1Z1VzAxZlZscTI4eHJSNFNEcjlPYUl3QmMzZGxaR1Z1WXkxa2MyMXoiLCJ4bXNfaWRyZWwiOiI3IDMwIiwieG1zX3JkIjoiMC40MkxsWUJKaUZCQVM0V0FYRXVDbzRuRm1ZaWx5bk10OEsySEM5c2kzUUZGT0lZRmdWOGIxaHFlelhlZXNzdm15NHFURmM2QW9oNUNBN2Z2Y21UbWJneDNiMkpmOXRXSGNNUjhBIiwieG1zX3N1Yl9mY3QiOiIzIDkifQ.GYBvO1R9-QQ9VJzoz4q_HaOYm8W0SsaK_bnhN6MoCx19S2oervAK6qFvDKgn01oF-fV1BPMiqFDfuK6WTQBq-BlR-FfxzskzBnskwsJdCVHyVKt_UW9l9FoX7iiAlkOPB7pcizOVKHq5MZC92VGocd20gp7S1sKymCD1ugWkwn0PYE6aIBP2EleQ3MAT3mPpihQ286F9X6CfR9AC-uMbqPu6ozD0bFOvzsbIWhEkw7CiZjch_HJZkpd-28R3CPo18vMNbru-cygLGiIsWEPSIt8l0e7diFW7CK1Mqf7cKoooh5EGTc49mpqKYZP9Axa-i0YsWP_poDdMyDNiTBoDAg" }
2. Global Headers
Every data request must include the following header:
Product & Inventory Endpoints
1. Retrieve Item List
Returns a high-level list of all products available for the specified company. It includes item's category, technical specifications, and commercial constraints.
Method: GET
Request URL: https://api.businesscentral.dynamics.com/v2.0/d18c2b33-dc88-4c06-b71c-67a7ba3d83fe/PRODUCTION/api/autocont/eshop/v2.0/companies(e5de3ad7-17fe-ed11-8f6e-000d3abde3ea)/items
If you want to retrieve product attributes for a single item, use the itemNumber filter.
Example URL: https://api.businesscentral.dynamics.com/v2.0/d18c2b33-dc88-4c06-b71c-67a7ba3d83fe/PRODUCTION/api/autocont/eshop/v2.0/companies(e5de3ad7-17fe-ed11-8f6e-000d3abde3ea)/items?$filter=itemNumber eq '{{item_number}}'
| Attribute | Logic / Description |
itemNumber |
The unique internal SKU/Identifier |
gtin |
The Global Trade Item Number (Barcode identifier). |
description |
Primary product name (e.g., Střídač AEG AS-IR01-5000-2). |
description2 |
Secondary identifier or technical model code. |
baseCategory |
The primary grouping (e.g., STRIDACE for Inverters, PANELY for Panels). |
vatCode |
The applicable tax code (e.g., DPH21Z for standard 21% VAT). |
salesBlocked |
If true, this item cannot be added to new Sales Orders. |
baseUnit |
The smallest inventory unit (usually KS for pieces). |
powerWp |
The nominal power rating (Watts peak). For Inverters/Panels. |
Pay attention to attribute "purchasingBlocked". If value is set to “true” then the selling for this item has been stopped.
2. Retrieve Prices
The SalesPrices endpoint returns an array of objects representing a specific price point valid under a unique set of conditions. To resolve the "actual" price for a customer, you must filter the results based on the hierarchy of Price List, Currency and Volume Tiers.
Method: GET
Request URL: Depends on price list that has been assigned to you by SOLSOL Sales Representative.
- Prices for price list "A"
https://api.businesscentral.dynamics.com/v2.0/d18c2b33-dc88-4c06-b71c-67a7ba3d83fe/PRODUCTION/api/autocont/eshop/v2.0/companies(e5de3ad7-17fe-ed11-8f6e-000d3abde3ea)/salesPricesA
- Prices for price list "VIP"
-
https://api.businesscentral.dynamics.com/v2.0/d18c2b33-dc88-4c06-b71c-67a7ba3d83fe/PRODUCTION/api/autocont/eshop/v2.0/companies(e5de3ad7-17fe-ed11-8f6e-000d3abde3ea)/salesPricesVIP - Prices for price list "VIP AJ"
https://api.businesscentral.dynamics.com/v2.0/d18c2b33-dc88-4c06-b71c-67a7ba3d83fe/PRODUCTION/api/autocont/eshop/v2.0/companies(e5de3ad7-17fe-ed11-8f6e-000d3abde3ea)/salesPricesVIPEN
To obtain prices from one specific product, use filter on parameter itemNumber.
Example for product with Item Number "001070" within price list "VIP": https://api.businesscentral.dynamics.com/v2.0/d18c2b33-dc88-4c06-b71c-67a7ba3d83fe/PRODUCTION/api/autocont/eshop/v2.0/companies(e5de3ad7-17fe-ed11-8f6e-000d3abde3ea)/salesPricesVIP?$filter=itemNumber eq '001070'
Primary Key Attributes
To identify the correct price record, evaluate these attributes in order:
|
Attribute |
Logic / Description |
|
|
The currency of the transaction. Note: If this field is empty ( |
|
|
The threshold for volume-based pricing. For certain items (e.g., Solar panels), the endpoint will return multiple pricing records with different It is used only for solar panels which can be purchased by individual piece, a palette or a shipping container. The applicable price can be found when searching for the highest
Example: order of 50 solar panels with itemNumber = 130471. For this product, the applicable levels are:
Therefore the target price can be found in object containing "minQuantity" = 37 |
|
|
The unit of measure (e.g., |
|
|
The net price per unit (excluding VAT). |
Volume Tiered Logic
Implementation Note: Always sort the filtered results by minQuantity in descending order. The first record where PurchaseQuantity >= minQuantity is the applicable price.
Quick Filter Cheat Sheet
If you need the price for a VIP AJ customer buying 50 units of product item '104500' in Czech Koruna:
- Filter
currency == ""(Empty string = CZK) -
Find the highest
minQuantitythat is =< 50 (In this case, the record withminQuantity: 36) -
Result:
unitPrice: 1518.29
3. Retrieve additional product attributes
While the main /Items endpoint already has basic product attributes, the assignedItemAttributes collection contains the technical specifications of the product. This endpoint is highly dynamic; different categories of products (e.g., Solar Panels vs. Inverters) will return different sets of attributes.
This data is crucial for building technical product sheets, comparing performance metrics, or filtering products by specific parameters like "Frame Color" or "Efficiency %".
Method: GET
Request URL: https://api.businesscentral.dynamics.com/v2.0/d18c2b33-dc88-4c06-b71c-67a7ba3d83fe/PRODUCTION/api/autocont/eshop/v2.0/companies(e5de3ad7-17fe-ed11-8f6e-000d3abde3ea)/items?$expand=assignedItemAttributes
To obtain prices from one specific product, use filter on parameter itemNumber.
Example for product with Item Number "104500": https://api.businesscentral.dynamics.com/v2.0/d18c2b33-dc88-4c06-b71c-67a7ba3d83fe/PRODUCTION/api/autocont/eshop/v2.0/companies(e5de3ad7-17fe-ed11-8f6e-000d3abde3ea)/items?$expand=assignedItemAttributes&$filter=itemNumber eq '104500'
To create a clean user interface (like a "Quick Specs" box), we recommend filtering the response based on the priorityView field
4. Retrieve Product Descriptions
To pull detailed product descriptions, including English, German, Polish and Czech translations, use the /ItemTranslations endpoint.
Method: GET
Request URL: https://api.businesscentral.dynamics.com/v2.0/d18c2b33-dc88-4c06-b71c-67a7ba3d83fe/PRODUCTION/api/autocont/eshop/v2.0/companies(e5de3ad7-17fe-ed11-8f6e-000d3abde3ea)/ItemTranslations
If you want to retrieve product description for a single item, use the itemNumber filter.
Example URL: https://api.businesscentral.dynamics.com/v2.0/d18c2b33-dc88-4c06-b71c-67a7ba3d83fe/PRODUCTION/api/autocont/eshop/v2.0/companies(e5de3ad7-17fe-ed11-8f6e-000d3abde3ea)/ItemTranslations?$filter=itemNumber eq '{{item_number}}'
This endpoint will return an English, German, Polish and Czech translations of product description.
| Attribute | Logic / Description |
| languageCode |
Common values: |
|
description |
Short product description. Use this field in case the |
|
marketingText |
Long product description. |
5. Retrieve Stock availabilities
To check how many units are available for sale, use the /items endpoint with parameter $expand=itemAvailability . This provides stock availability across all our warehouses grouped by logical regions.
Method: GET
Request URL: https://api.businesscentral.dynamics.com/v2.0/d18c2b33-dc88-4c06-b71c-67a7ba3d83fe/PRODUCTION/api/autocont/eshop/v2.0/companies(e5de3ad7-17fe-ed11-8f6e-000d3abde3ea)/items?$expand=itemAvailability
If you want to retrieve stock availability for a single item, use the itemNumber filter.
Example URL: https://api.businesscentral.dynamics.com/v2.0/d18c2b33-dc88-4c06-b71c-67a7ba3d83fe/PRODUCTION/api/autocont/eshop/v2.0/companies(e5de3ad7-17fe-ed11-8f6e-000d3abde3ea)/items?$expand=itemAvailability&$filter=itemNumber eq '104500'
| Attribute | Logic / Description |
|
|
The geographical or logical region (e.g., ! Only use stock quantities where |
|
|
Total physical units currently located in that region. |
|
|
The "Sellable" Quantity: Total physical units minus existing reservations. |
6) Retrieve composition of product sets
The endpoint /bomComponents retrieves the breakdown of Product Sets (Assembly BOMs). It identifies exactly which individual components—and in what quantities—constitute a specific parent product (identified by itemNumber).
Method: GET
Request URL: https://api.businesscentral.dynamics.com/v2.0/d18c2b33-dc88-4c06-b71c-67a7ba3d83fe/PRODUCTION/api/autocont/eshop/v2.0/bomComponents
To find the composition of a specific set, it is recommended to use the OData $filter parameter.
Example URL: https://api.businesscentral.dynamics.com/v2.0/d18c2b33-dc88-4c06-b71c-67a7ba3d83fe/PRODUCTION/api/autocont/eshop/v2.0/bomComponents?$filter=itemNumber eq '201001'
The response returns an array of component objects within the value field.
Sample response:
{
"@odata.context": "https://api.businesscentral.dynamics.com/v2.0/d18c2b33-dc88-4c06-b71c-67a7ba3d83fe/PRODUCTION/api/autocont/eshop/v2.0/$metadata#companies(e5de3ad7-17fe-ed11-8f6e-000d3abde3ea)/bomComponents",
"value": [
{
"@odata.etag": "W/\"JzE5OzIyNDA1NTQ2OTkwMDU5Nzc3ODgxOzAwOyc=\"",
"id": "cd915341-e566-f011-8eed-7c1e527211f1",
"createdDateTime": "2025-07-22T10:18:48.83Z",
"lastModifiedDateTime": "2025-07-22T10:18:48.83Z",
"itemNumber": "201001",
"lineNumber": 10000,
"componentType": "Item",
"componentNumber": "201101",
"componentAssemblyBOM": false,
"description": "AEG střídač AS-ICH02-10000-2/HV",
"quantityPer": 1,
"unit": "KS",
"position": "",
"position2": "",
"position3": ""
},
{
"@odata.etag": "W/\"JzE5OzY1OTU2MTAzMDAzMzk5ODQ4NDYxOzAwOyc=\"",
"id": "e16a2c4e-e566-f011-8eed-7c1e527211f1",
"createdDateTime": "2025-07-22T10:19:17.18Z",
"lastModifiedDateTime": "2025-07-22T10:19:17.18Z",
"itemNumber": "201001",
"lineNumber": 20000,
"componentType": "Item",
"componentNumber": "301102",
"componentAssemblyBOM": false,
"description": "AEG AS-BBH1-10000/HV V2",
"quantityPer": 1,
"unit": "KS",
"position": "",
"position2": "",
"position3": ""
}
]
}
itemNumber 201001 consists of 1 piece of item 201101 ("AEG střídač AS-ICH02-10000-2/HV") and 1 piece of item 301102 ("AEG AS-BBH1-10000/HV V2").| Field | Type | Description |
| itemNumber | string | The unique identifier for the Parent Set/Product. |
| componentNumber | string | The unique identifier for the individual component within the set. |
| description | string | Human-readable name of the component. |
| quantityPer | decimal | The number of units of this component required to create one unit of the parent set. |
| unit | string | The Unit of Measure for the quantity (e.g., "KS" for pieces). |
| componentType | string | The type of line item (typically "Item" or "Resource"). |
| lineNumber | integer | The sequential position of the component within the assembly list. |
| componentAssemblyBOM | boolean | Indicates if this component is itself a set (Nested BOM). |
3. Common error Codes
|
Status Code |
Meaning |
Troubleshooting |
|
401 |
Unauthorized |
Token is missing, expired, or invalid. |
|
403 |
Forbidden |
Client ID is authenticated but lacks permission for this CompanyID. |
|
404 |
Not Found |
The CompanyID or Endpoint URL is incorrect. |
|
429 |
Too Many Requests |
Rate limit exceeded. Please implement a back-off strategy. |