Create annotation to a contact entity in Microsoft Dynamics CRM by API

Part 1:
MS Docs Reference: Deep Insert

You can create entities related to each other by defining them as navigation properties values. This is known as deep insert. 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.

Below code is to create Account (1), create + associate Primary contact (2), create & Associate Opportunity (3) and create + associate Task (4)

POST [Organization URI]/api/data/v8.2/accounts HTTP/1.1
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" }
      ]
  }
 ]
}

Part 2:
Associating annotation to contact uses the below syntax.

note["[email protected]"] = "/contacts(C5DDA727-B375-E611-80C8-00155D00083F)";

Refer SO link & blog

Part 3:
Answer to your comment on another answer about annotation_id_from_first_request:

To get the created record Id in response from last request, you can parse like below:

                //get Response from Created Record
                entityIdWithLink = XMLHttpRequest.getResponseHeader("OData-EntityId");
 
                //get EntityId from ResponseHeader of Created Record  
                getEntityId = entityIdWithLink.split(/[()]/);
                getEntityId = getEntityId[1];

You can read more

You can compose your POST request so that data from the created record will be 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.
The $expand query option will be ignored if used. When an entity is created in this way the OData-EntityId header containing the URI to the created record is not returned

Note: This capability was added with December 2016 update for Dynamics 365

MS Docs Reference: Create with data returned

Update:
If anyone looking for working payload sample to deep insert a record + annotation, the below is from my project:

data = {
        "new_attribute1": "test attribute 1",
        "new_attribute2": "test attribute 2",
        "new_comments": "test comments",
        "new_recordurl": recordURL,
        "new_feedback_Annotations":
            [
                {
                    "notetext": "Screenshot attached",
                    "subject": "Attachment",
                    "filename": file.name,
                    "mimetype": file.type,
                    "documentbody": base64str,
                }
            ]
    };

I've found this working, but in two requests:

POST [organization URI]/api/data/annotations
Content-Type: application/json; charset=utf-8
Accept: application/json
{
    "notetext": "TEST"
}

POST [organization URI]/api/data/contacts(f76e4e7c-ea61-e511-80fd-3863bb342b00)/Contact_Annotation/$ref
Content-Type: application/json; charset=utf-8
Accept: application/json
{
    "@odata.id": "[organization URI]/annotations(annotation_id_from_first_request)"
}

Edit:

annotation_id_from_first_request value is taken form first request's response.


Instead of using [email protected], you have to use [email protected]. This results are in:

"[email protected]": "/contacts(f76e4e7c-ea61-e511-80fd-3863bb342b00)"

To get the list of properties, look under the single-valued navigation properties in the documentation.