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 environment, allowing authorized 3rd parties to read master data for products, units of measure, and commercial terms.

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.


1. 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

[POST] https://login.microsoftonline.com/d18c2b33-dc88-4c06-b71c-67a7ba3d83fe/oauth2/v2.0/token

Request Body Params:

  • 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>

2.

Product & Inventory Endpoints

A.

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.

[GET] 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


Pay attention to attribute "purchasingBlocked". If value is set to “true” then the selling of such item has been stopped.

B.

2. Retrieve Prices

To obtain prices from one specific price list, use filter on parameter validForCode.

Example for price list “VIP AJ”:

[GET] https://api.businesscentral.dynamics.com/v2.0/d18c2b33-dc88-4c06-b71c-67a7ba3d83fe/PRODUCTION/api/autocont/eshop/v2.0/companies(e5de3ad7-17fe-ed11-8f6e-000d3abde3ea)/salesPrices?$filter=validForCode eq 'VIP AJ'

Pricing Data Structure

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, the consuming application must filter the results based on the hierarchy of Currency, Price List, and Volume Tiers.

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.

validForCode

The Price List or Customer Group (e.g., VIP AJ).

minQuantity

The threshold for volume-based pricing. The applicable price is the one where the purchase quantity is >= minQuantity.

unit

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


Volume Tiering Logic

The endpoint provides "Step Pricing." For a single currency and price list, multiple records will exist with different minQuantity values.

Example for Product 128453 (EUR):

  • Tier 1: 0–35 units -> 57.33 EUR (minQuantity: 0)

  • Tier 2: 36–935 units -> 52.78 EUR (minQuantity: 36)

  • Tier 3: 936+ units → 50.51 EUR (minQuantity: 936)

Implementation Note: Always sort the filtered results by minQuantity in descending order. The first record where PurchaseQuantity >= minQuantity is the applicable price.

Field Mapping Reference

  • unitPrice: The net price per unit (excluding VAT).

  • unitPriceInclVat: The gross price per unit (including VAT).

Quick Filter Cheat Sheet (Example)

If you need the price for a VIP AJ customer buying 50 units in Czech Koruna:

  1. Filter validForCode == "VIP AJ"

  2. Filter currency == "" (Empty string = CZK)

  3. Find the highest minQuantity that is =< 50 (In this case, the record with minQuantity: 36).

  4. Result: unitPrice: 1313.166

C.

3. Retrieve Product Translations

To pull translations of product descriptions, use the /ItemTranslations endpoint

[GET] 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

To pull product descriptions just for one specific PLU, use the $filteroperator on itemNumber. API may return multiple objects for a single item to support multi-language variations.

[GET] 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 '104403'

  • Marketing Content: The primary commercial description for e-shop is located in the marketingText field.

  • Short Descriptions: Use the description field for the technical product name/title (e.g., "FV panel Canadian Solar...")

Note: If marketingText is empty for a specific item, we recommend falling back to the description field as a secondary title.


D.

4. Retrieve SellingProduct Units

Descriptions

To pull detailed descriptions and unit-of-measure data,descriptions, use the /ItemTranslations endpoint with following parameter ?$expand=itemUnitsendpoint.

Method: HTTP GET

Request URL: [GET] https://api.businesscentral.dynamics.com/v2.0/d18c2b33-dc88-4c06-b71c-67a7ba3d83fe/PRODUCTION/api/autocont/eshop/v2.0/companies({{CompanyID}}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}}'

Returns a list of products including their core metadata and a detailed breakdown of available selling units. This endpoint iswill essentialreturn foran determiningEnglish, howGerman, aPolish and Czech translations of product candescription. be ordered—whether as individual pieces, full palettes, or shipping containers.

Each item defines a Base Unit (typically pieces), while the expanded itemUnits collection provides the conversion logic and physical dimensions for alternative packaging options.



Field

Description

unitlanguageCode

The unit code. Common values: KSDEU(German), ENU(English), PLK(Polish), CSY (Piece), PALETA (Palette), CTN (Container).Czech)

quantityPerdescription

TheShort conversionproduct factor.description. RepresentsUse howthis many Base Units are containedfield in thiscase specificthe unitmarketingText (e.g.,field 37is pieces per Palette).empty.

weightmarketingText

TheLong grossproduct weight for this specific unit quantity in kilograms (kg).

dimensions

(Length, Width, Height) The physical size of the unit package.description.



E.

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: HTTP GET

Request URL: GEThttps://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

Example request:
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'

Example 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)/itemAvailability",
    "value": [
        {
            "@odata.etag": "W/\"JzIwOzEzMjYyODQ1ODQ1ODY5ODUwOTg4MTswMDsn\"",
            "warehouseGroupId": "1",
            "warehouseGroupName": "CZ",
            "itemNumber": "104500",
            "unit": "KS",
            "quantityOnStock": 513,
            "quantityAvailable": -371.00000
        },
        {
            "@odata.etag": "W/\"JzE5OzIxOTI3MjcyNjkxMzc1ODkwNTExOzAwOyc=\"",
            "warehouseGroupId": "2",
            "warehouseGroupName": "NL",
            "itemNumber": "104500",
            "unit": "KS",
            "quantityOnStock": 0,
            "quantityAvailable": 0
        },
        {
            "@odata.etag": "W/\"JzE5OzUwODIwNDA1MjU3ODY3ODM4NTExOzAwOyc=\"",
            "warehouseGroupId": "3",
            "warehouseGroupName": "CESTA",
            "itemNumber": "104500",
            "unit": "KS",
            "quantityOnStock": 0,
            "quantityAvailable": 0
        }
    ]
}



Field

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.





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.