Dataverse Organization Service vs Web API

By Emil Björk · Microsoft business apps consultant, Gothenburg

How the two Dataverse SDK surfaces differ — SOAP-era IOrganizationService vs the OData v4 Web API.

Reviewed May 20263 min read · 645 wordsPublished
On this page (5)

Dataverse exposes two programmatic surfaces with overlapping capability and very different ergonomics: the Organization Service (IOrganizationService, SDK-based, historically SOAP) and the Web API (REST/OData v4). Both are first-class; both will continue to be supported. Understanding when each fits is foundational for any developer writing code against Dataverse.

Organization Service.

  • The classic SDK surface dating to Dynamics CRM.
  • Strongly-typed via Microsoft.PowerPlatform.Dataverse.Client package (recently rebranded from Microsoft.Xrm.Sdk).
  • Originally SOAP; current implementation uses HTTPS and a SOAP-compatible client.
  • Supports Entity records, EntityCollection, QueryExpression, FetchExpression.
  • The native API for plugins — plugins receive an IOrganizationService reference and operate through it.
  • C# / .NET first; limited support in other languages.

Web API.

  • REST endpoints exposed at /api/data/v9.2/ on every Dataverse environment.
  • OData v4 compliant; works with any HTTP client.
  • JSON request/response.
  • Action and function support for custom operations.
  • The native API for client-side code (model-driven app JavaScript, Power Pages Liquid extensions).
  • Cross-language: PowerShell, Python, JavaScript, Power Automate HTTP actions, anything that speaks HTTP.

When Organization Service wins.

  • Plugin development — you have an IOrganizationService passed in; using it is natural.
  • Bulk operations with .NET — strongly typed collections and the SDK's batch APIs.
  • Workflow assemblies — custom workflow activities in .NET.
  • Legacy code maintenance — existing solutions built on it.

When Web API wins.

  • JavaScript / TypeScript — model-driven app form scripts and ribbon commands.
  • Non-.NET languages — Python data scripts, Node.js services, PowerShell automation.
  • External integrations — third-party services calling Dataverse from outside.
  • Power Automate — built-in connector uses the Web API.
  • Browser-based toolsXrmToolBox alternatives.

Performance

Both surfaces ultimately route through the same Dataverse engine; raw performance is similar. Operational differences:

  • Web API has clearer batching semantics$batch endpoint for multi-request bundles.
  • Organization Service has ExecuteMultiple for bundling .NET calls.
  • Web API native streaming for large result sets via $skiptoken paging.
  • OData query string syntax is more idiomatic in URL form than SOAP-era expression objects.

Authentication.

  • Both support OAuth 2.0 via Microsoft Entra ID (Azure AD).
  • Service principals (application user) and user-context tokens supported on both.
  • Web API additionally easier to call from external systems given REST nature.

Common operations on both.

OperationOrganization ServiceWeb API
Create recordservice.Create(entity)POST /accounts
Update recordservice.Update(entity)PATCH /accounts(id)
Delete recordservice.Delete(entityName, id)DELETE /accounts(id)
Retrieveservice.Retrieve(...)GET /accounts(id)
QueryRetrieveMultiple(QueryExpression)GET /accounts?$filter=...
FetchXMLRetrieveMultiple(FetchExpression)GET /accounts?fetchXml=...
BulkExecuteMultiplePOST /$batch
Custom actionExecute(OrganizationRequest)POST /CustomAction

FetchXML

Both surfaces accept FetchXML — the Dataverse-native query language. For complex queries involving joins, aggregations, and link entities, FetchXML is more expressive than OData. Use it on either surface.

Choosing in plugins

Inside a plugin, IOrganizationService is what you have — use it. Calling the Web API from a plugin is technically possible but adds HTTP overhead unnecessarily.

Choosing in JavaScript

Inside a form script or web resource, the Web API is what's available — use it. Specifically Xrm.WebApi.* functions wrapping the Web API are idiomatic.

Choosing in external code.

  • .NET — Organization Service via ServiceClient from Microsoft.PowerPlatform.Dataverse.Client. Cleaner code, types.
  • Python / Node / PowerShell / curl — Web API. No SDK, just HTTP and JSON.

OData specifics worth knowing.

  • $select — pick columns to return.
  • $expand — include related records.
  • $filter — query criteria.
  • $top, $skip — paging.
  • $orderby — sort.
  • MaxPageSize header — server-side paging size.

Composing these correctly is the difference between fast and slow Web API code.

Common pitfalls.

  • Mixing surfaces in one solution. Some plugins call Web API, some use Organization Service; inconsistency. Pick a convention per project.
  • Web API paging missed. Without paging logic, large result sets return only first page; downstream code thinks data is complete.
  • OAuth token expiry. Tokens last 1 hour; long-running scripts need refresh logic.
  • Locale and formatting. Web API returns ISO timestamps; Organization Service returns .NET DateTime; conversion needs care.
  • Schema name vs display name confusion. Web API uses logical names (new_customfield); ensure correct casing.

Operational rule

Choose by language: .NET → Organization Service. Anything else → Web API. Both surfaces will remain supported indefinitely; investing in either is safe. The choice is about ergonomics, not capability.

Frequently asked questions

Which API should I use from a plug-in?

The Organization Service. A plug-in receives an IOrganizationService reference; calling the Web API from inside it only adds HTTP overhead.

Which API should I use from JavaScript or an external system?

The Web API — REST and OData v4 at /api/data/v9.2/, callable from any HTTP client. Xrm.WebApi wraps it for model-driven form scripts, and Power Automate's Dataverse connector uses it too.

Is the Organization Service deprecated?

No. It lives on in the Microsoft.PowerPlatform.Dataverse.Client package with a SOAP-compatible client, and both surfaces will remain supported. The choice is about ergonomics per language, not capability.

How do I do bulk operations?

ExecuteMultiple on the Organization Service, or the $batch endpoint on the Web API. Both surfaces accept FetchXML for complex queries, and both need explicit paging for result sets beyond the first page.

Related guides

Browse every guide in Customer Engagement or just Dataverse platform.

Was this helpful?

Signals which guides land and which need work. No account, no comment box — corrections go through the contact page.

Spot something wrong or want a topic covered? Send a correction or a topic request — both are welcome.