Create a table row using the Web API

Use a POST request to send data to create a table row (entity record). You can create multiple related table rows in a single operation using deep insert. You also need to know how to set values to associate a new table row to existing tables using the @odata.bind annotation.

Note

For information about how to create and update the table (entity) definitions using the Web API, see Create and update table definitions using the Web API.

Basic create

This example creates an new account entity record. accounts is the entity set name for the account EntityType. The response OData-EntityId header contains the URI of the created entity.

Request:


POST [Organization URI]/api/data/v9.2/accounts
Content-Type: application/json; charset=utf-8
OData-MaxVersion: 4.0
OData-Version: 4.0
Accept: application/json

{
    "name": "Sample Account",
    "creditonhold": false,
    "address1_latitude": 47.639583,
    "description": "This is the description of the sample account",
    "revenue": 5000000,
    "accountcategorycode": 1
}

Response:


HTTP/1.1 204 No Content
OData-Version: 4.0
OData-EntityId: [Organization URI]/api/data/v9.2/accounts(7eb682f1-ca75-e511-80d4-00155d2a68d1)

To create an record you must identify the valid entity set name, property names, and types.

Note

In Power Apps, when viewing a list of tables, select Advanced > Tools. Select Copy set name to copy the entity set name for the table.

You can also select API link to table data to view the top 10 rows of data in your browser. This works best when you have a browser extension like JSON formatter installed that will format the JSON text data returned.

The entity set name isn't always the same as the collection name or plural name of the table. It is stored a separate property called EntitySetName.

When you create a new table row, you can't insert a non-primary image at the same time. For a non-primary image to be added, the row must already exist. Learn more about primary images

For all system tables and attributes (table columns), you can find this information in the article for that entity in the Web API Entity Type Reference. For custom tables or columns, refer to the definition of that table in the CSDL $metadata document. More information: Web API EntityTypes

Setting the primary key value

Each table has a unique identifier primary key column which you can specify when creating a row. In most cases you should allow the system to set this for you because the values generated by the system are optimized for best performance.

With elastic tables, you can create records with duplicate primary key values and different partitionid values. However, this pattern is not compatible with model-driven or canvas Power Apps. Learn about setting the primary key value with elastic tables

Create with data returned

You can compose your POST request so that data from the created record is returned with a status of 201 (Created). To get this result, you must use the return=representation preference in the request headers.

To control which properties are returned, append the $select query option to the URL to the entity set. You may also use $expand to return related entities.

Nested $expand on collection-valued navigation properties will not return data when used with the return=representation preference. More information: Nested $expand on collection-valued navigation properties

When an entity is created in this way, the OData-EntityId header containing the URI to the created record isn't returned.

This example creates a new account entity and returns the requested data in the response.

Request:


POST [Organization URI]/api/data/v9.2/accounts?$select=name,creditonhold,address1_latitude,description,revenue,accountcategorycode,createdon
OData-MaxVersion: 4.0
OData-Version: 4.0
Accept: application/json
Content-Type: application/json; charset=utf-8
Prefer: return=representation

{
   "name": "Sample Account",
   "creditonhold": false,
   "address1_latitude": 47.639583,
   "description": "This is the description of the sample account",
   "revenue": 5000000
}

Response:


HTTP/1.1 201 Created
Content-Type: application/json; odata.metadata=minimal
Preference-Applied: return=representation
OData-Version: 4.0

{
    "@odata.context": "[Organization URI]/api/data/v9.2/$metadata#accounts/$entity",
    "@odata.etag": "W/\"536530\"",
    "accountid": "d6f193fc-ce85-e611-80d8-00155d2a68de",
    "accountcategorycode": 1,
    "description": "This is the description of the sample account",
    "address1_latitude": 47.63958,
    "creditonhold": false,
    "name": "Sample Account",
    "createdon": "2016-09-28T22:57:53Z",
    "revenue": 5000000.0000,
    "_transactioncurrencyid_value": "048dddaa-6f7f-e611-80d3-00155db5e0b6"
}

Create multiple records in a single request

The fastest way to create multiple records of the same type in a single request is to use the CreateMultiple action. At the time of this writing the CreateMultiple action. Not all standard tables support this action, but all elastic tables do.

More information:

With standard tables, you can create entities related to each other by defining them as navigation properties values. This pattern is known as deep insert. This approach has two advantages. It's more efficient, because it replaces replacing multiple simpler creation and association operations with one combined atomic operation. An atomic operation succeeds or fails entirely.

As with a basic create, the response OData-EntityId header contains the URI of the created entity. The URIs for the related entities created aren't returned. You can get the primary key values of the records if you use the Prefer: return=representation header so it returns the values of the created record. Learn more about creating records with data returned

For example, the following request body posted to the accounts entity set creates a total of four records in the context of creating an account.

  • A contact is created with firstname and lastname values because it's defined as an object property of the single-valued navigation property named primarycontactid.

  • An opportunity related to the account is created because it's defined as an object in an array that's set to the value of a collection-valued navigation property named opportunity_customer_accounts.

  • A task related to the opportunity is created because it's defined an object in an array that's set to the value of a collection-valued navigation property named Opportunity_Tasks.

Request:

POST [Organization URI]/api/data/v9.2/accounts
Content-Type: application/json; charset=utf-8
OData-MaxVersion: 4.0
OData-Version: 4.0
Accept: application/json

{
 "name": "Sample Account",
 "primarycontactid":
 {
     "firstname": "John",
     "lastname": "Smith"
 },
 "opportunity_customer_accounts":
 [
  {
      "name": "Opportunity associated to Sample Account",
      "Opportunity_Tasks":
      [
       { "subject": "Task associated to opportunity" }
      ]
  }
 ]
}

Response:


HTTP/1.1 204 No Content
OData-Version: 4.0
OData-EntityId: [Organization URI]/api/data/v9.2/accounts(3c6e4b5f-86f6-e411-80dd-00155d2a68cb)

Associate table rows on create

To associate new records with existing records when they're created, use the @odata.bind annotation to set the value of navigation properties.

The following request body posted to the accounts entity set creates an account associated with an existing contact with the contactid value of 00000000-0000-0000-0000-000000000001 and two existing tasks with activityid values of 00000000-0000-0000-0000-000000000002 and 00000000-0000-0000-0000-000000000003.

This request is using the Prefer: return=representation header so it returns the values of the created record. More information: Create with data returned

Request:


POST [Organization URI]/api/data/v9.2/accounts?$select=name&$expand=primarycontactid($select=fullname),Account_Tasks($select=subject)
Content-Type: application/json; charset=utf-8
OData-MaxVersion: 4.0
OData-Version: 4.0
Accept: application/json
Prefer: return=representation

{
    "name": "Sample Account",
    "primarycontactid@odata.bind": "/contacts(00000000-0000-0000-0000-000000000001)",
    "Account_Tasks@odata.bind": [
        "/tasks(00000000-0000-0000-0000-000000000002)",
        "/tasks(00000000-0000-0000-0000-000000000003)"
    ]
}

Response:


HTTP/1.1 201 Created
OData-Version: 4.0
Preference-Applied: return=representation

{
    "@odata.context": "[Organization URI]/api/data/v9.2/$metadata#accounts(name,primarycontactid(fullname),Account_Tasks(subject))/$entity",
    "@odata.etag": "W/\"36236432\"",
    "name": "Sample Account",
    "accountid": "00000000-0000-0000-0000-000000000004",
    "primarycontactid": {
        "@odata.etag": "W/\"28877094\"",
        "fullname": "Yvonne McKay (sample)",
        "contactid": "00000000-0000-0000-0000-000000000001"
    },
    "Account_Tasks": [
        {
            "@odata.etag": "W/\"36236437\"",
            "subject": "Task 1",
            "activityid": "00000000-0000-0000-0000-000000000002"
        },
        {
            "@odata.etag": "W/\"36236440\"",
            "subject": "Task 2",
            "activityid": "00000000-0000-0000-0000-000000000003"
        }
    ]
}

Check for duplicate records

By default, duplicate detection is suppressed when you're creating records. To enable duplicate detection, include the MSCRM.SuppressDuplicateDetection: false header with your POST request to enable duplicate detection. Duplicate detection only applies when the following conditions are true:

  • The organization has enabled duplicate detection.
  • The entity is enabled for duplicate detection.
  • Active duplicate detection rules are applied.

More information:

Create a record from another record

Use the InitializeFrom function to create a record in the context of an existing record where the relationship between the tables is mapped. For information about creating these mappings, see:

To determine whether two entities can be mapped, use the following query:

GET [Organization URI]/api/data/v9.2/entitymaps?
$select=sourceentityname,targetentityname&$orderby=sourceentityname

Creating a new record from another record is a two-step process. First, use the InitializeFrom function to return property values mapped from the original record. Then, combine the response data returned in the InitializeFrom function with any changes you want to make and then POST the data to create the record.

The following example shows how to create an account record using the values of an existing account record with accountid value equal to 00000000-0000-0000-0000-000000000001.

Step 1: Get the data with InitializeFrom

Request:

GET [Organization URI]/api/data/v9.2/InitializeFrom(EntityMoniker=@p1,TargetEntityName=@p2,TargetFieldType=@p3)?
@p1={'@odata.id':'accounts(00000000-0000-0000-0000-000000000001)'}&
@p2='account'&@p3=Microsoft.Dynamics.CRM.TargetFieldType'ValidForCreate'
If-None-Match: null
OData-Version: 4.0
OData-MaxVersion: 4.0
Content-Type: application/json
Accept: application/json

Response:

{
    "@odata.context": "[Organization URI]/api/data/v9.2/$metadata#accounts/$entity",
    "@odata.type": "#Microsoft.Dynamics.CRM.account",
    "parentaccountid@odata.bind": "accounts(00000000-0000-0000-0000-000000000001)",
    "transactioncurrencyid@odata.bind": "transactioncurrencies(732e87e1-1d96-e711-80e4-00155db75426)",
    "address1_line1": "123 Maple St.",
    "address1_city": "Seattle",
    "address1_country": "United States of America"
}

Step 2: Create the new record

The response received from InitializeFrom function consists of values of mapped columns between the source table and target table and the GUID of the parent record. The column mapping between tables that have a relationship is different for different tables and is customizable, so the response from InitializeFrom function request will vary for different organizations.

Other property values can also be set and/or modified for the new record by adding them in the JSON request body, as shown in the following example:

POST [Organization URI]/api/data/v9.2/accounts
Content-Type: application/json; charset=utf-8
OData-MaxVersion: 4.0
OData-Version: 4.0
Accept: application/json

    {
        "@odata.context": "[Organization URI]/api/data/v9.2/$metadata#accounts/$entity",
        "@odata.type": "#Microsoft.Dynamics.CRM.account",
        "parentaccountid@odata.bind": "accounts(00000000-0000-0000-0000-000000000001)",
        "transactioncurrencyid@odata.bind": "transactioncurrencies(732e87e1-1d96-e711-80e4-00155db75426)",
        "name":"Contoso Ltd",
        "numberofemployees":"200",
        "address1_line1":"100 Maple St.",
        "address1_city":"Seattle",
        "address1_country":"United States of America",
        "fax":"73737"
    }
}

Create documents in storage partitions

If you're creating large numbers of records for elastic tables, you can create the entities in storage partitions to speed up access to those entity records.

Learn about creating records in an elastic table

See also

Web API basic operations sample (C#)
Web API basic operations sample (Client-side JavaScript)
InitializeFrom function
Perform operations using the Web API
Compose HTTP requests and handle errors
Query data using the Web API
Retrieve a table row using the Web API
Update and delete table rows using the Web API
Associate and disassociate table rows using the Web API
Use Web API functions
Use Web API actions
Execute batch operations using the Web API
Impersonate another user using the Web API
Perform conditional operations using the Web API