Custom service or OData action in D365 F&O: which to choose?
Expose D365 F&O X++ logic: OData action on a data entity, or custom JSON/SOAP service. Differences, syntax and use cases from Microsoft Learn.
The short answer
To expose X++ logic to an external system, Dynamics 365 Finance & Operations offers two main paths:
- An OData action: a method added to a public data entity and decorated with SysODataActionAttribute. It appears in the OData $metadata and is called from the service URL. Ideal when the operation concerns an entity that is already exposed.
- A custom service: an X++ class attached to a service and a service group. Each group is automatically deployed to two endpoints, SOAP and JSON (/api/services/group/service/operation). Suited to operations that match no entity, such as a real-time on-hand inventory lookup, a scenario for which Microsoft recommends a custom service.
Writing an OData action
Microsoft Learn example: the method is added to the entity; the attribute's first argument is the action's public name, the second says whether it is always available.
[SysODataActionAttribute("CalcMaintenanceDuration", true)]
public int CalculateMaintenanceDuration()
{
//do something
return 0;
}To return a typed collection, add SysODataCollectionAttribute (parameter name, or return; X++ type of the items; public resource name):
[SysODataActionAttribute("GetColors", true),
SysODataCollectionAttribute("return", Types::Record, "CarColor")]
public List GetColorsByAvailability(boolean onlyAvailableVehicles)
{
List returnList = new List(Types::Record);
// do something
return returnList;
}Writing a custom service
- Create an X++ class with public methods; use data contract classes (DataContract) for complex parameters.
- Create a Service element pointing to the class and declare its operations.
- Add the service to a service group: all groups under the Service group node are deployed automatically.
- Call the JSON endpoint https://<host>/api/services/<group>/<service>/<operation> or the SOAP endpoint /soap/services/<group>?wsdl, with Microsoft Entra ID authentication.
For a call from an AI agent, the modern path is different: a class exposed as an AI tool through the Dynamics 365 ERP MCP server. See Copilot Studio agents: what still needs X++.
Common mistakes
- Creating a custom service for CRUD that an OData data entity already covers.
- Forgetting to add the service to a group: it is not deployed.
- Making single OData calls for large volumes: Microsoft directs large volumes to asynchronous APIs (DMF package, recurring integrations).
- Forgetting security: the entry point (service, entity) must be covered by a privilege linked to the client application's role.
- Returning a type an OData action does not support: primitive types or a public updatable entity.
Having it generated
OData action, JSON service, contracts and security: short, testable developments. Skalp AI writes the specification, generates the X++ code and unit tests, compiles with a best-practice check, then delivers a pull request to your Azure DevOps: nothing is merged without your technical architect's approval. See D365 F&O API interfaces, the bigger picture in building X++ without a consultant in 2026, and the Basic, Pro and Max plans (1 credit, ≈ €400 on Basic, €200 on Pro, consumed only when the code is generated).
Sources
- Microsoft Learn, "Open Data Protocol (OData)", updated 14 Jan 2026, accessed 18 Oct 2026.
- Microsoft Learn, "Custom service development", updated 29 Oct 2025, accessed 18 Oct 2026.
- Microsoft Learn, "Integration between finance and operations apps and third-party services", updated 9 Mar 2026, accessed 18 Oct 2026.
Frequently asked questions
What is the URL of a custom JSON service?
https://<host>/api/services/<service_group>/<service>/<operation>, according to Microsoft Learn.
Can an OData action return a list?
Yes, with SysODataCollectionAttribute specifying the item type and the public resource name.
OData or custom service for a real-time lookup?
If the data matches an exposed entity, OData. For logic that matches no entity, such as a computed stock lookup, Microsoft recommends a custom service.
Ready to transform your D365?
Join the CIOs who develop their D365 tickets in 2–4 h for 1 credit (≈ €400 on Basic, €200 on Pro).