Search code examples
apiodatamicrosoft-dynamicsdynamics-business-central

MS Dynamics 365 Business Central. API POST, PATCH, DELETE does not work


We have installed on our server MS Dynamics 365 Business Central (I don't know how to view currently installed version). We are using oData v4 protocol for our requests.

Task

We need to make API calls to this system from PHP

Issue

It's impossible to make POST, PATCH, DELETE requests when GET request works well.

GET

Request:

GET https://d365bc.vendor.com:7058/attain/ODataV4/Company('{{company}}')/Customer

Response

{
    "@odata.context": "https://d365bc.vendor.com:7058/attain/ODataV4/$metadata#Company('...')/Customer",
    "value": [
        {
            "@odata.etag": "W/\"JzQ0O29EcmJmcGs4V3NRMHlEQ0Fxa0JxL1N0bi9xZjY5UDFQakZ0U2tBUGU1Kzg9MTswMDsn\"",
            "No": "01121212",
            "Name": "Spotsmeyer's Furnishings",
            "Responsibility_Center": "",
            "Location_Code": "YELLOW",
            "Post_Code": "US-FL 37125",
            "Country_Region_Code": "US",
            "Phone_No": "",
            "IC_Partner_Code": "",
            "Contact": "Mr. Mike Nash",
            "Salesperson_Code": "JR",
            "Customer_Posting_Group": "FOREIGN",
            "Gen_Bus_Posting_Group": "EXPORT",
            "VAT_Bus_Posting_Group": "EXPORT",
            "Customer_Price_Group": "",
            "Customer_Disc_Group": "",
            "Payment_Terms_Code": "1M(8D)",
            "Reminder_Terms_Code": "FOREIGN",
            "Fin_Charge_Terms_Code": "2.0 FOR.",
            "Currency_Code": "USD",
            "Language_Code": "ENU",
            "Search_Name": "SPOTSMEYER'S FURNISHINGS",
            "Credit_Limit_LCY": 0,
            "Blocked": " ",
            "Privacy_Blocked": false,
            "Last_Date_Modified": "2020-06-18",
            "Application_Method": "Manual",
            "Combine_Shipments": true,
            "Reserve": "Optional",
            "Shipping_Advice": "Partial",
            "Shipping_Agent_Code": "",
            "Base_Calendar_Code": "",
            "Balance_LCY": 0,
            "Balance_Due_LCY": 0,
            "Sales_LCY": 0,
            "Global_Dimension_1_Filter": "",
            "Global_Dimension_2_Filter": "",
            "Currency_Filter": "",
            "Date_Filter": "..11/13/20"
        },
        {
            "@odata.etag": "W/\"JzQ0O08vNlVHSWVaZ1FGeG42d2JOa3k4Qm5uVHlkSGYzNk1ES2V5Y2E2S3hiekU9MTswMDsn\"",
            "No": "01445544",
            "Name": "Progressive Home Furnishings",
            "Responsibility_Center": "",
            "Location_Code": "YELLOW",
            "Post_Code": "US-IL 61236",
            "Country_Region_Code": "US",
            "Phone_No": "",
            "IC_Partner_Code": "",
            "Contact": "Mr. Scott Mitchell",
            "Salesperson_Code": "JR",
            "Customer_Posting_Group": "FOREIGN",
            "Gen_Bus_Posting_Group": "EXPORT",
            "VAT_Bus_Posting_Group": "EXPORT",
            "Customer_Price_Group": "",
            "Customer_Disc_Group": "RETAIL",
            "Payment_Terms_Code": "14 DAYS",
            "Reminder_Terms_Code": "FOREIGN",
            "Fin_Charge_Terms_Code": "2.0 FOR.",
            "Currency_Code": "USD",
            "Language_Code": "ENU",
            "Search_Name": "PROGRESSIVE HOME FURNISHINGS",
            "Credit_Limit_LCY": 0,
            "Blocked": " ",
            "Privacy_Blocked": false,
            "Last_Date_Modified": "2018-09-19",
            "Application_Method": "Manual",
            "Combine_Shipments": true,
            "Reserve": "Optional",
            "Shipping_Advice": "Partial",
            "Shipping_Agent_Code": "",
            "Base_Calendar_Code": "",
            "Balance_LCY": 1499.03,
            "Balance_Due_LCY": 1499.03,
            "Sales_LCY": 1499.03,
            "Global_Dimension_1_Filter": "",
            "Global_Dimension_2_Filter": "",
            "Currency_Filter": "",
            "Date_Filter": "..11/13/20"
        },

DELETE

DELETE https://d365bc.vendor.com:7058/attain/ODataV4/Company('{{company}}')/Customer(No='01121212')
{
    "error": {
        "code": "BadRequest",
        "message": "Entity does not support delete."
    }
}

I'm not sure what is the correct syntax for the Create (POST) or Update (Patch) For the POST request I tried to copy existing value (taken from GET) and put it into the body. I'm getting following response:

{
    "error": {
        "code": "BadRequest_MethodNotAllowed",
        "message": "Entity does not support insert."
    }
}

Sometimes if I make absolutely wrong request I'm getting following response:

{
    "error": {
        "code": "BadRequest_MethodNotAllowed",
        "message": "'POST' requests for 'Customer' of EdmType 'Entity' are not allowed within Microsoft Dynamics 365 Business Central OData web services."
    }
}

I'm unable to apply CUD operations for Customers, ProductItems. However for orders it works.

Existing Privileges

If I follow

Setup & Extensions / Manual Setup / Users / [Select User]

In the permissions section, there are too many assigned privileges. Among them, there is a SUPER privileges item. As I know all names are custom there. Here is the screenshot of the assigned privileges.

enter image description here

UPD 1.

I tried to follow this guide: https://learn.microsoft.com/en-us/dynamics-nav/api-reference/v1.0/

I have on-prem installation and for me it's not clear what is the correct endpoint for any operation.

For example I can make following request:

https://d365bc.vendor.com:7057/attain/WS/CRONUS%20International%20Ltd/Page/Customer

And as result, I'm getting some scheme, but not customers, or the possibility to make any actions with them.

As I understood this guide has examples for cloud installation only.

Extension APIs:
https://<base URL>:<port>/<serverinstance>/api/<API publisher>/<API group>/<API version>

Am I doing everything correct? What do these params mean? No explanation provided in the guide.

Upd.2

Regarding requirements:

API must be enabled on the Business Central server instance:

enter image description here

So port is 7057, API URL is https://d365bc.vendor.com:7057/Attain/WS/

What is WS, is it really required? By the URL above I'm getting this:

enter image description here

The user used for authentication must have a Web Service Access Key (created for the user in Business Central)

There was nothing in this section, I've added new key. And now it looks like this. But it didn't change anything in my case. Still same errors: 405 for the port 7057 and 404 for the port 7058.

enter image description here

p.s. Is it enough to simply generate it? Or we need to use it somewhere?

The user must have the required permissions within Business Central for the relevant API's.

Is it managing at the following page?

enter image description here

Here are responses examples:

enter image description here enter image description here

Url was changed after execution with the correct Vendor name in the domain name.

I'm unable to test everything right now, as I'm far away from my laptop on vac. Thanks everyone for your time


Solution

  • The paramaters are as follows:

    1. base URL: the name of the server e.g. d365bc.vendor.com
    2. port: the port used for OData e.g. 7058
    3. serverinstance: the name of the Business Central server instance e.g. attain
    4. API publisher: used for grouping of custom API's (not required when using the standard API's)
    5. API group: used for grouping of custom API's (not required when using the standard API's)
    6. API version: used for grouping of custom API's (not required when using the standard API's)

    The combination of base URL, port and server instance can be located under OData Services and the field OData Base URL on the Business Central service tier settings.

    The base endpoint you need to use is (based on the information you supplied):

    // Version 13
    https://d365bc.vendor.com:7058/Attain/api/beta
    
    // Version 14+
    https://d365bc.vendor.com:7058/Attain/api/v1.0
    

    To work with the API's you first need to get an id for the company - so you get the company list:

    // Version 13
    https://d365bc.vendor.com:7058/Attain/api/beta/companies
    
    // Version 14+
    https://d365bc.vendor.com:7058/Attain/api/v1.0/companies
    

    With your company id you can then get a list of customers:

    // Version 13
    https://d365bc.vendor.com:7058/Attain/api/beta/companies([company id here!])/customers
    
    // Version 14+
    https://d365bc.vendor.com:7058/Attain/api/v1.0/companies([company id here!])/customers
    

    You would use the same endpoint for POST or PATCH by providing the required data as json in the request body.

    Requirements:

    1. API must be enabled on the Business Central server instance
    2. The user used for authentication must have a Web Service Access Key (created for the user in Business Central)
    3. The user must have the required permissions within Business Central for the relevant API's.

    Comments:

    • Some of the API's only support GET. This means you would get the 405 Not allowed error for POST or PATCH.
    • You might need to add If-Match * to the request headers for PATCH operations.

    Response to UPD.2:

    • Port 7057 and https://d365bc.vendor.com:7057/Attain/WS/ is for SOAP Web Services and is not to be confused with API. You need the port 7058 as stated under the OData Services tab.

    • To assign a Web Service Access Key you must navigate to Users in Business Central, find the user in question and click the button Change Web Service Key.