Dax365FO

Making the invisible visible




Introduction

This article summarizes the different ways to perform API requests through OData. We will present template to use, when we develop this kind of integration. It is the preferred approach for handling large volumes of records. In other words, it’s the perfect solution whether you need to create, update, retrieve, or delete data.


Technical specification

Key concepts

The request must be sent to a specific URL address.

Each request consists of two main header’s elements and a body:

    Headers:

    Body:

    • Data: JSON data (used when creating or updating a record).

    Addressing

    The address is structured basically in this way:

    https://{environment url}/data/{resource}
    https://example.sandbox.operations.dynamics.com/data/CustomerGroups

    List of all resources

    The resource represents the “data entity” in D365FO, and the name is usually the same. To retrieve the list of all available resources, you can query D365FO as follows. As response we will have the full list:

    GET https://{environment url}/data
    https://example.sandbox.operations.dynamics.com/data

    Filter specific record/field from keys

    Sometimes we need to target a specific record (for example to update or delete it). In this case, we can add a filter directly in the URL to retrieve that record. We can filter for keys variables (separate them by a comma):

    https://{environment url}/data/{resource(insert your keys filter)}
    https://example.sandbox.operations.dynamics.com/data/CustomerGroups(CustomerGroupId='10',dataAreaId='usmf')

    We can even decide to target a specific field:

    https://{environment url}/data/{resource(insert your keys filter)}/Field
    https://example.sandbox.operations.dynamics.com/data/CustomerGroups(CustomerGroupId='10',dataAreaId='usmf')/Description

    Query Parameters

    Cross-company

    D365FO return the data from the legal entity configurated on the user related to our application (see this article for setup details: https://dax365fo.org/2026/06/03/azure-application-registration/):

    However, if you want to extract data from another legal entity, set the cross-company parameter as true. This returns data from all legal entities, so add an additional filter on dataAreaId to retrieve records for a specific legal entity.

    https://{environment url}/data/{Resource}?cross-company=true&$filter=dataAreaId eq {legal entity}
    https://example.operations.dynamics.com/data/CustomerGroups?cross-company=true&$filter=dataAreaId eq 'usmf'

    $filter

    As mentioned by the name this query parameter filter the data. The operator available are:

    • Equals (eq)
    • Not equals (ne)
    • Greater than (gt)
    • Greater than or equal (ge)
    • Less than (lt)
    • Less than or equal (le)
    • And
    • Or
    • Not
    • Addition (add)
    • Subtraction (sub)
    • Multiplication (mul)
    • Division (div)
    • Decimal division (divby)
    • Modulo (mod)
    • Precedence grouping ({ })

    Notice, that we can filter by several criteria using and/or:

    https://{environment url}/data/{resource}?filter={criteria}
    https://example.operations.dynamics.com/data/CustomerGroups?filter=dataAreaId eq 'usmf' and PaymentTermId eq 'Net30'

    Other paramters

    They are rarely used in practice. But for more details on how to use thm, see this article: https://www.linkedin.com/pulse/working-odata-protocol-dynamics-365-finance-operations-syed-amir-ali-8wbaf/


    Request template

    The information provided in the technical specification are sufficient to build the OData integration. However, here are examples of requests to perform CRUD operations. You can reuse them to build your own requests.

    The resource uses for our template example is: CustomerGroups.

    Create

    Request to create data record in D365FO.

    Method: POST

    Address: {environment url}/data/{resource}

    Header:

    Parameters:

    • Empty

    Body:

    • Insert the JSON of the data to create

    Address example:

    https://example.operations.dynamics.com/data/CustomerGroups

    Body example:

    {
    "dataAreaId": "usmf",
    "CustomerGroupId": "980",
    "Description": "Testing odata"
    }

    D365FO will return the data of the record just created:

    Read

    Request to read data from D365FO.

    Method: GET

    Address: {environment url}/data/{resource}

    Header:

    Parameters:

    • cross-company=true
    • &filter=dataAreaId eq ‘{insert the legal entity}’

    Body:

    • Empty

    Address example:

    https://example.operations.dynamics.com/data/CustomerGroups?cross-company=true&$filter=dataAreaId eq 'usmf'

    D365FO will return the data based on the query:

    Update

    Request to update a data in D365FO.

    Method: PATCH

    Address: {environment url}/data/{resource(insert your keys filter)}

    Header:

    Parameters:

    • cross-company=true

    Body:

    • Insert the JSON of the data to update

    Address example:

    https://example.sandbox.operations.dynamics.com/data/CustomerGroups(CustomerGroupId='980',dataAreaId='usmf')?cross-company=true

    Body example

    {
    "Description": "Testing odata update"
    }

    D365FO will return the confirmation status 204:

    Delete

    Request to delete a data in D365FO.

    Method: DELETE

    Address: {environment url}/data/{resource(insert your keys filter)}

    Header:

    Parameters:

    • cross-company=true

    Body:

    • Empty

    Address example:

    https://example.sandbox.operations.dynamics.com/data/CustomerGroups(CustomerGroupId='980',dataAreaId='usmf')?cross-company=true

    D365FO will return the confirmation status 204:

    Leave a comment