Search code examples
odatadynamics-business-central

How to create a contact using Business Central API 2.0?


(NOTE: The documentation mentioned below is wrong at the time of this submission. It looks like it was copied from a template and not changed. I've submitted comment on Microsoft's GitHub page.)

Has anyone had success creating a contact using the Business Central v2 API? I'm following the documentation here and not having any success. Updates work great, but I can't get create requests working at all.

The documentation says I should be able to post to the contacts end-point like so,

POST businesscentralPrefix/companies({id})/contacts({id})

The fact that {id} is used as a placeholder for both companies and contacts URL components is strange and not at all what I would expect. A more complete example is also given on that page:

POST https://{businesscentralPrefix}/api/v2.0/companies({id})/contacts({id})
Content-type: application/json
{
    "id" : "5d115c9c-44e3-ea11-bb43-000d3a2feca1",
    "number" : "108001",
    "type" : "Company",
    "displayName": "CRONUS USA, Inc.",
    "companyNumber" : "17806",
    "companyName" : "CRONUS US",
    "businessRelation" : "Vendor",
    "addressLine1": "7122 South Ashford Street",
    "addressLine2": "Westminster",
    "city": "Atlanta",
    "state": "GA",
    "country": "US",
    "postalCode": "31772",
    "phoneNumber": "+1 425 555 0100",
    "mobilePhoneNumber" : "",
    "email" : "[email protected]",
    "website" : "",
    "searchName" : "",
    "privacyBlocked" : true,
    "lastInteractionDate" : "2021-06-01",
    "lastModifiedDateTime" : "2021-06-01"
}

The example has an id property in the payload, which doesn't seem like something I should be creating. Again the id here is confusing given the duplicate {id} placeholders in the URL.

Additionally, there are some header requirements that don't make sense for a create request:

If-Match Required. When this request header is included and the eTag provided does not match the current tag on the contact, the contact will not be updated.

I won't have an etag if I'm creating a contact, so that header doesn't seem to apply to create requests. If that's the case, then probably can't rely much on the documentation. If that's the case, then I can't help but wonder if the create end-point shouldn't be:

POST https://{businesscentralPrefix}/api/v2.0/companies({company-guid})/contacts

which seems more consistent with other REST APIs I've encountered, but leaves me wondering whether or not I need supply the id for the new contact? I'm going with "no", but Microsoft's documentation doesn't mention it outside of the examples.

I have no problems updating an existing contact. I'm left with three options for creating one:

  1. POST https://{businesscentralPrefix}/api/v2.0/companies({company-guid})/contacts({company-guid})

    This one is what the docs imply, but it doesn't make any sense given that you're effectively filtering the contacts table by a company id. I gave it a shot just for the sake of it

POST https://{businesscentralPrefix}/api/v2.0/companies({company-guid})/contacts({company-guid})
{
    "id":"8adc4ec5-8393-44ac-8860-fadd9e3603cb",
    "number": "TEST123",
    "displayName": "Another Test Contact",
    "type": "Person",
    ...
}
...
Response (with and without the contact guid in payload)
{
    "error": {
        "code": "BadRequest_MethodNotAllowed",
        "message": "'POST' requests for 'contacts' of EdmType 'Entity' are not allowed within Dynamics 365 Business Central OData web services.  CorrelationId:  XXX"
    }
}
  1. POST https://{businesscentralPrefix}/api/v2.0/companies({company-guid})/contacts({contact-guid})

    this one also seems weird since it doesn't seem like I should be creating the record's id. Also tried it just to try it:

POST https://api.businesscentral.dynamics.com/v2.0/{tenent-guid}/{environment}/api/v2.0/companies({company-guid})/contacts(8adc4ec5-8393-44ac-8860-fadd9e3603cb)
{
    "id":"8adc4ec5-8393-44ac-8860-fadd9e3603cb",
    "number": "TEST123",
    "displayName": "Another Test Contact",
    "type": "Person",
    ...
}
...
Response (with and without the contact id guid in payload)
{
    "error": {
        "code": "BadRequest_MethodNotAllowed",
        "message": "'POST' requests for 'contacts' of EdmType 'Entity' are not allowed within Dynamics 365 Business Central OData web services.  CorrelationId:  XXXX."
    }
}
  1. POST https://{businesscentralPrefix}/api/v2.0/companies({company-guid})/contacts

    Number 3 makes sense in my mind but fails with

POST https://api.businesscentral.dynamics.com/v2.0/{tenent-guid}/{environment}/api/v2.0/companies({company-guid})/contacts(8adc4ec5-8393-44ac-8860-fadd9e3603cb)

{
    "id":"8adc4ec5-8393-44ac-8860-fadd9e3603cb",
    "number": "TEST123",
    "displayName": "Another Test Contact",
    "type": "Person",
    ...
}
...
Response (with and without the contact id guid in payload)
{
    "error": {
        "code": "Internal_RecordNotFound",
        "message": "The Contact does not exist. Identification fields and values: No.='TEST123'  CorrelationId:  XXX."
    }
}

Has anyone had success creating a contact using the Business Central v2 API? If so, how did you do it and what am I doing wrong? Also, the system I'm working with was upgrade from a local NAV instance, fwiw.


Solution

  • The error seems to occur when both number and type is included in the payload.

    The solution would be to create the contact without either number or type and then update the value you left out with a patch request.