Dataverse Organization Service vs Web API

How the two Dataverse SDK surfaces differ — SOAP-era IOrganizationService vs the OData v4 Web API — and when each is the right choice for code that touches Dataverse.

Updated 2026-07-01

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.

| Operation | Organization Service | Web API | |---|---|---| | Create record | service.Create(entity) | POST /accounts | | Update record | service.Update(entity) | PATCH /accounts(id) | | Delete record | service.Delete(entityName, id) | DELETE /accounts(id) | | Retrieve | service.Retrieve(...) | GET /accounts(id) | | Query | RetrieveMultiple(QueryExpression) | GET /accounts?$filter=... | | FetchXML | RetrieveMultiple(FetchExpression) | GET /accounts?fetchXml=... | | Bulk | ExecuteMultiple | POST /$batch | | Custom action | Execute(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.

Related guides