Do not use the OData v2.0 endpoint

Category: Supportability

Impact potential: High

Symptoms

There are no immediate symptoms, but code that uses this endpoint will stop working when the deprecated endpoint is removed.

The original removal date was November 11, 2022. It was extended to April 30, 2023. We decided not to remove the service on April 30, 2023, to give people more time to transition their code to use the Web API. If you're still using this endpoint, you must prioritize transitioning your code to use the Web API so that you're prepared when the final removal date is announced. More information: OData v2.0 Service removal date announcement.

Guidance

You should change any code that depends on the Organization Data Service (OData v2.0) to use the Dataverse Web API (OData v4.0) endpoint instead.

For model-driven apps, you should use the Xrm.WebApi (client API reference), which provides access to the Dataverse Web API for client-side extensions that use JavaScript web resources.

Problematic patterns

The Organization Data Service uses this endpoint: /XRMServices/2011/OrganizationData.svc. You should look for any active code that uses this endpoint.

The Dynamics CRM SDK provided an example JavaScript library as a JavaScript web resource named sample_/Scripts/SDK.REST.js, which can be found here. The Xrm.WebApi (client API reference) provides similar functions to create, update, delete, and retrieve records.

PowerShell scripts that use Invoke-WebRequest also sometimes use the Organization Data Service endpoint.

Additional information

The Organization Data Service is an OData v2.0 endpoint that was introduced with Dynamics CRM 2011. It was deprecated with Dynamics 365 Customer Engagement v8.0. Also known as the OData endpoint or REST endpoint when it was released, this endpoint only supports create, retrieve, update, and delete operations on tables.

Both the Dataverse Web API and Organization Data service are OData endpoints, but there are differences in how they are implemented. Do not expect that existing code will work with only minor changes.

Some of the major differences are described in the sections that follow.

Resource names

Web API resource names for tables are based on the EntitySetName. Organization Data Service names had Set appended to the SchemaName.

Web API Organization Data Service
accounts AccountSet
contacts ContactSet
tasks TaskSet

Column names

Column names in the Web API are all lowercase and use the LogicalName. In the Organization Data Service, column names use the SchemaName.

HTTP methods

The Organization Data Service uses MERGE or PUT rather than PATCH to update a record.

Data format

The Organization Data Service supports both JSON and ATOM, an XML-based format usually used for RSS feeds. The Web API only supports JSON.

Limits on number of records returned

The Organization Data Service will only return 50 records at a time and doesn't provide a way to specify max page size.

The Web API allows you to set a max page size and will return up to 5000 records. More information: Page results

Legacy documentation

Organization Data Service documentation: Microsoft Dynamics 2015 SDK: Use the OData endpoint with web resources.

The following table connects related areas for the Organization Data Service and the Web API:

Organization Data Service Web API
Query Microsoft Dynamics CRM 2015 data using the OData endpoint
OData system query options using the OData endpoint
Query data
Web API properties
Creating records Create a table row
Retrieving records Retrieve a table row
Updating records Basic update
Deleting records Basic delete
Using Deep insert Create related table rows in one operation
Updating individual properties Update a single property value
Associating and disassociating records Associate and disassociate table rows
OData endpoint HTTP status codes Identify status codes

Examples

This section highlights the differences between using the Organization Data Service and the Web API.

The Organization Data Service only supports create, retrieve, update, and delete operations on tables. The following examples illustrate the differences between the services to help you migrate to the Web API.

Query records

These examples show the differences between the Organization Data Service and the Web API when you query records.

The Organization Data Service has no way to manage paging other than using $top and $skip. The maximum page size is 50 records.

Request:

GET  [Organization URI]/XRMServices/2011/OrganizationData.svc/AccountSet?$select=OwnershipCode,PrimaryContactId,OpenDeals_Date,Telephone1,NumberOfEmployees,Name,AccountNumber,DoNotPhone,IndustryCode&$filter=PrimaryContactId/Id ne null&$top=2 HTTP/1.1
Accept: application/json

Response:

HTTP/1.1 200 OK
Cache-Control: no-cache
Allow: OPTIONS,GET,HEAD,POST
Content-Type: application/json;charset=utf-8

{
  "d": {
    "results": [
      {
        "__metadata": {
          "uri": " [Organization URI]/xrmservices/2011/OrganizationData.svc/AccountSet(guid'7a4814f9-b0b8-ea11-a812-000d3a122b89')",
          "type": "Microsoft.Crm.Sdk.Data.Services.Account"
        },
        "OwnershipCode": {
          "__metadata": {
            "type": "Microsoft.Crm.Sdk.Data.Services.OptionSetValue"
          },
          "Value": 2
        },
        "PrimaryContactId": {
          "__metadata": {
            "type": "Microsoft.Crm.Sdk.Data.Services.EntityReference"
          },
          "Id": "dff27d1f-a61b-4bfe-a203-b2e5a36cda0e",
          "LogicalName": "contact",
          "Name": "Sam Smith",
          "RowVersion": null
        },
        "OpenDeals_Date": "/Date(1663715691000)/",
        "Telephone1": "555-1234",
        "NumberOfEmployees": 500,
        "Name": "Contoso, Ltd. (sample)",
        "AccountNumber": "1111",
        "DoNotPhone": false,
        "IndustryCode": {
          "__metadata": {
            "type": "Microsoft.Crm.Sdk.Data.Services.OptionSetValue"
          },
          "Value": 7
        }
      },
      {
        "__metadata": {
          "uri": " [Organization URI]/xrmservices/2011/OrganizationData.svc/AccountSet(guid'fed58509-4af3-ec11-bb3d-000d3a1a51c1')",
          "type": "Microsoft.Crm.Sdk.Data.Services.Account"
        },
        "OwnershipCode": {
          "__metadata": {
            "type": "Microsoft.Crm.Sdk.Data.Services.OptionSetValue"
          },
          "Value": null
        },
        "PrimaryContactId": {
          "__metadata": {
            "type": "Microsoft.Crm.Sdk.Data.Services.EntityReference"
          },
          "Id": "ffd58509-4af3-ec11-bb3d-000d3a1a51c1",
          "LogicalName": "contact",
          "Name": "Susie Curtis",
          "RowVersion": null
        },
        "OpenDeals_Date": "/Date(1663715691000)/",
        "Telephone1": null,
        "NumberOfEmployees": null,
        "Name": "Fourth Coffee",
        "AccountNumber": null,
        "DoNotPhone": false,
        "IndustryCode": {
          "__metadata": {
            "type": "Microsoft.Crm.Sdk.Data.Services.OptionSetValue"
          },
          "Value": null
        }
      }
    ]
  }
}

When more than 50 records are returned, use the __next property to access the next page.

"__next": "https://[Organization URI]/XRMServices/2011/OrganizationData.svc/AccountSet?$select=OwnershipCode,PrimaryContactId,OpenDeals_Date,Telephone1,NumberOfEmployees,Name,AccountNumber,DoNotPhone,IndustryCode&$filter=PrimaryContactId/Id ne null&$skiptoken=1,'accountid','%7B22153355-851D-ED11-B83E-000D3A572421%7D','%7B7A4814F9-B0B8-EA11-A812-000D3A122B89%7D'"

Create records

These examples show the differences between the Organization Data Service and the Web API when you create records.

Request:

POST [Organization URI]/XRMServices/2011/OrganizationData.svc/AccountSet HTTP/1.1
Accept: application/json
Content-Type: application/json

{
  "OwnershipCode": {
    "Value": 2
  },
  "PrimaryContactId": {
    "Id": "dff27d1f-a61b-4bfe-a203-b2e5a36cda0e",
    "LogicalName": "contact"
  },
  "OpenDeals_Date": "12/25/2022",
  "CustomerSizeCode": {
    "Value": 1
  },
  "Telephone1": "555-1234",
  "NumberOfEmployees": 500,
  "Name": "Contoso, Ltd. (sample)",
  "AccountNumber": "12225",
  "DoNotPhone": true,
  "IndustryCode": {
    "Value": 7
  }
}

Response:

With the Organization Data Service, all properties are returned when a record is created.

HTTP/1.1 201 Created
Content-Type: application/json;charset=utf-8
REQ_ID: a0c614be-50be-4c1e-9413-1c7ba459c5c9

{
  "d": {
    "__metadata": {
      "uri": "[Organization URI]/xrmservices/2011/OrganizationData.svc/AccountSet(guid'57d4d1af-7b38-ed11-9db0-002248296d7e')",
      "type": "Microsoft.Crm.Sdk.Data.Services.Account"
    },
    "AccountId": "57d4d1af-7b38-ed11-9db0-002248296d7e",

    <All properties are returned. Removed for brevity>

  }
}

Retrieve records

These examples show the differences between the Organization Data Service and the Web API when you retrieve records.

Request:

GET https://[Organization URI]/XRMServices/2011/OrganizationData.svc/AccountSet(guid'b68d56a6-4739-ed11-9db0-002248296d7e')?$select=OwnershipCode,PrimaryContactId,OpenDeals_Date,Telephone1,NumberOfEmployees,Name,AccountNumber,DoNotPhone,IndustryCode HTTP/1.1
Accept: application/json

Response:

HTTP/1.1 200 OK

{
  "d": {
    "__metadata": {
      "uri": "https://[Organization URI]/xrmservices/2011/OrganizationData.svc/AccountSet(guid'b68d56a6-4739-ed11-9db0-002248296d7e')",
      "type": "Microsoft.Crm.Sdk.Data.Services.Account"
    },
    "OwnershipCode": {
      "__metadata": {
        "type": "Microsoft.Crm.Sdk.Data.Services.OptionSetValue"
      },
      "Value": 2
    },
    "PrimaryContactId": {
      "__metadata": {
        "type": "Microsoft.Crm.Sdk.Data.Services.EntityReference"
      },
      "Id": "dff27d1f-a61b-4bfe-a203-b2e5a36cda0e",
      "LogicalName": "contact",
      "Name": "Sam Smith",
      "RowVersion": null
    },
    "OpenDeals_Date": "/Date(1663784098000)/",
    "Telephone1": "555-1234",
    "NumberOfEmployees": 500,
    "Name": "Contoso, Ltd. (sample)",
    "AccountNumber": "12227",
    "DoNotPhone": true,
    "IndustryCode": {
      "__metadata": {
        "type": "Microsoft.Crm.Sdk.Data.Services.OptionSetValue"
      },
      "Value": 7
    }
  }
}

Update records

These examples show the differences between the Organization Data Service and the Web API when you update records.

The Organization Data Service requires the X-HTTP-Method: MERGE request header to be applied with a POST request.

Request:

POST https://[Organization URI]/XRMServices/2011/OrganizationData.svc/AccountSet(guid'b68d56a6-4739-ed11-9db0-002248296d7e') HTTP/1.1
Accept: application/json
X-HTTP-Method: MERGE
Content-Type: application/json

{
  "OwnershipCode": {
    "Value": 3
  },
  "PrimaryContactId": {
    "Id": "6db0be2e-d01c-ed11-b83e-000d3a572421"
  },
  "OpenDeals_Date": "12/26/2022",
  "Telephone1": "555-1235",
  "NumberOfEmployees": 501,
  "Name": "Contoso, Ltd.",
  "AccountNumber": "12228",
  "DoNotPhone": false,
  "IndustryCode": {
    "Value": 6
  }
}

Response:

HTTP/1.1 204 No Content

Delete records

These examples show the differences between the Organization Data Service and the Web API when you delete records.

Request:

DELETE https://[Organization URI]/XRMServices/2011/OrganizationData.svc/AccountSet(guid'b68d56a6-4739-ed11-9db0-002248296d7e') HTTP/1.1
Accept: application/json

Response:

HTTP/1.1 204 No Content

See Also

How to use Application Insights to identify usage of the OrganizationData.svc endpoint which is planned for retirement in November 2022 (Community Forum)
How to use Solution Checker to identify usage of the OrganizationData.svc endpoint which is planned for retirement in November 2022 (Community Forum)
Use the Microsoft Dataverse Web API