If you are working on a project which involves integrating a third party application to Microsoft Dynamics 365 Business Central, then I assume you have already come across with the Business Central APIs. 

I noticed that most of the developers are still not comfortable with the endpoints of the BC APIs. Therefore this blog post is about how to understand the BC API endpoints.

Endpoint contains a couple of sections.

Sections of the URL
Purpose
https://api.businesscentral.dynamics.com
Base URL. This will be the same for all the out-of-the-box APIs and for custom APIs
/v1.0
Version
/your tenant domain
Domain name or ID
/environment name
Environment name. Can get the name from the admin portal. Ex: production, sandbox
/api
This is a keyword
/beta 
The version of the API.

** from this point onwards "https://api.businesscentral.dynamics.com" will be referred to as "{BaseURL}

If you want to use out-of-the-box API then the endpoint would be : 
{BaseURL}/v1.0/<your tenant domain>/<environment name>/api/beta  

Might get an error like below when calling the endpoint even though the correct credentials were provided with the request. 

1
2
3
4
5
6
{
"error": {
"code": "Authentication_InvalidCredentials",
"message": "The server has rejected the client credentials."
}
}

I encountered this recently and manage to find the reason behind this. Above endpoint will only work if your tenant version is below 14.1. If the tenant version is 14.1 or above then it is a must to use the API version 2.0. (yet to confirm by the Microsoft)

For the tenant which are 14.1 or above endpoint would be:


{BaseURL}/v2.0/<your tenant domain>/<environment name>/api/beta   

Result body will contain all the out-of-the-box APIs for Business Central.

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
"value": [
{
"name": "items",
"kind": "EntitySet",
"url": "items"
},
{
"name": "companies",
"kind": "EntitySet",
"url": "companies"
},
{
"name": "customers",
"kind": "EntitySet",
"url": "customers"
}
]
}

Before you call any other API it is a must to point the URL to a specific company. In order to do that you can call the below Endpoint
Tenant version is below 14.1:

{BaseURL}/v1.0/<your tenant domain>/<environment name>/api/beta/companies

Tenant version is 14.1 or above:


{BaseURL}/v2.0/<your tenant domain>/<environment name>/api/beta/companies

It will return all the companies available in the tenant. 

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
"value": [
{
"id": "e3dbe661-9c12-47d0-81f8-1186bd32518ab",
"systemVersion": "34093",
"name": "CRONUS NZ",
"displayName": "CRONUS NZ",
"businessProfileId": ""
},
{
"id": "e15523c2-b04f-438c-b1bc-756321a91fae",
"systemVersion": "34093",
"name": "My Company",
"displayName": "My Company",
"businessProfileId": ""
}
]
}

Version 14.1 and above treat segments as collections. Therefore it is a must to use ( ) when specifying a single record in all the new tenant versions. 

Tenant version is below 14.1:

{BaseURL}/v1.0/<your tenant domain>/<environment name>/api/beta/companies/<companyID>

Tenant version is 14.1 or above:

{BaseURL}/v2.0/<your tenant domain>/<environment name>/api/beta/companies(<companyID>)

Once you select the company, you can call the other entities in the same way you call the companies. 

As an example below calls will give you the list of items available. 
Tenant version is below 14.1:
{BaseURL}/v1.0/<your tenant domain>/<environment name>/api/beta/companies/<companyID>/items

Tenant version is 14.1 or above:

{BaseURL}/v2.0/<your tenant domain>/<environment name>/api/beta/companies(<companyID>)/items

If you want to retrieve a single item then below can be used
Tenant version is below 14.1:
{BaseURL}/v1.0/<your tenant domain>/<environment name>/api/beta/companies/<companyID>/items/<itemID>

Tenant version is 14.1 or above:

{BaseURL}/v2.0/<your tenant domain>/<environment name>/api/beta/companies(<companyID>)/items(<itemID)

Good luck and happy integration!

Please provide your feedback with a comment. 
Thank you and Regards,
Tharanga Chandrasekara