It doesn't quite feel right to me on the empty vs null front - playing around with the API explorer in 4.7.15, but what I can say is if I do an api call for a contact ID (say, 3) with nickname IS NULL as follows:
CRM.api3('Contact', 'get', {
"sequential": 1,
"id": 3,
"nick_name": {"IS NULL":1}
})
I come up with the result for cid 3 including "nick_name": "",
(which would say to me that it's empty instead of IS NULL... but comes up with the previous api call anyways.
Then I run the following test by adding a nickname:
CRM.api3('Contact', 'create', {
"sequential": 1,
"contact_type": "Individual",
"id": 3,
"nick_name": "nickname"
})
and run the same GET query as above, and get no results as follows:
{
"is_error": 0,
"version": 3,
"count": 0,
"values": []
}
If I then run:
CRM.api3('Contact', 'create', {
"sequential": 1,
"contact_type": "Individual",
"id": 3,
"nick_name": ""
})
and run the first GET query... I come up with the same result as the beginning again... which appears to be a contact with nickname empty ("") rather than null.
TLDR; It looks like you can use
CRM.api3('Contact', 'create', {
"sequential": 1,
"contact_type": "Individual",
"id": 3,
"nick_name": ""
})
even though it doesn't feel quite right... if you're trying to pull that contact up with "nickname IS NULL" searches using the api.