Skip to main content

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:

  • Authorization: Bearer <Your_access_token>

Product & Inventory Endpoints

1. Retrieve Item List

Returns a high-level list of all products available in our portfolio. 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 EN"
    • 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

currency

The currency of the transaction. Note: If this field is empty (""), the price refers to CZK.

minQuantity

The threshold for volume-based pricing. For certain items (e.g., Solar panels), the endpoint will return multiple pricing records with different minQuantity values.

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 minQuantity that is =< 50

 

Example: order of 50 solar panels with itemNumber = 130471. For this product, the applicable levels are: 

  • minQuantity= 0 (ordering by piece)
  • minQuantity= 37 (ordering by palette)
  • minQuantity = 962 (ordering by container)

Therefore the target price can be found in object containing "minQuantity" = 37

unit

The unit of measure (e.g., KS for pieces).

unitPrice

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 AJEN  customer buying 50 units of product item '104500' in Czech Koruna:

  1. Filter currency == "" (Empty string = CZK)
  2. Find the highest minQuantity that is =< 50 (In this case, the record with minQuantity: 36)

  3. 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: DEU (German), ENU (English), PLK (Polish), CSY (Czech)

description

Short product description. Use this field in case the marketingText field is empty.

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

warehouseGroupName

The geographical or logical region (e.g., CZ for Czechia, NL for Netherlands).

! Only use stock quantities where warehouseGroupName = CZ !

quantityOnStock

Total physical units currently located in that region.

quantityAvailable

The "Sellable" Quantity: Total physical units minus existing reservations.
Use this field for e-shop sync.


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/companies(e5de3ad7-17fe-ed11-8f6e-000d3abde3ea)/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": ""
        }
    ]
}
Based on the response it can be concluded, that set with 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).

7. Retrieve product category translations

To obtain a list of all possible Item Categories, including their multi-language translations, use the $expand parameter on the
/itemCategories 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)/itemCategories?$expand=itemCategoryTranslations

Each object in the value array represents a specific product category. The translation details are embedded directly within each category object. 

The endpoint supports a nested structure. You can identify relationships using parentId and indentation.

  • Root Example: category: "BATERIE" has a parentId of all zeros and indentation: 0.

  • Child Example: category: "KABELY" has indentation: 1 and parentCategory: "PRISLUSENSTVI".

Instead of making separate calls for every language, the $expand property allows the frontend to cache all translations at once. When a user switches the site language to Polish (PLK), the app can instantly look up the description "Kable" from the itemCategoryTranslations array.


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.