I'm trying to troubleshoot an issue I'm having with api v3. I can successfully use the api to modify standard CiviCRM contact fields, but if I use the api to modify a contact's custom field the call never completes.

In the api explorer I can create a call to modify a custom field on a contact and click "execute", but nothing is returned – no response or error, the icon in the results box just continues to spin. I'm not seeing an error in the log file either.

So this api call does not execute:

$result = civicrm_api3('Contact', 'create', [
  'debug' => 1,
  'id' => 4,
  'custom_6' => 1,

And this one executes successfully:

$result = civicrm_api3('Contact', 'create', [
  'debug' => 1,
  'id' => 4,
  'do_not_email' => 1,

I feel like I am missing something obvious like a wrong permission, but would it return an error on that? Any ideas of where to look to troubleshoot?


To try and reproduce this, I visited the CiviCRM.org demo site at https://dmaster.demo.civicrm.org/, logged in, and explored the API Explorer there. You might prefer to use a demo site that matches your platform / version (& note that some folk have found the CiviCRM.org hosted demo sites can be hard to spot beneath the partner-hosted sites on that page).

I found a contact via the regular CiviCRM UI and edited their "Marital Status" and "Most Important Issue" constituent info on the contact edit screen, then used the API explorer to return the custom data which had been set.

enter image description here enter image description here

I then used the same process to try and update the custom data, setting "Marital Status" to "M" (the API explorer presents available options in a list).

enter image description here

This showed a successful result and I confirmed that the update worked by viewing the contact record and seeing that "Other" had now changed to "Married". This indicates that the CiviCRM.org demo site works for this use case (suggesting that the issue you're experiencing might be configuration or permission-dependent, or related to some other site-specific implementation detail).

By observing the network tab while testing these API calls, I could observe the response from CiviCRM. In the event where an API call via JS doesn't return a result, I'd look here to see if there was an unexpected response (either invalid JSON, which could possibly leave CiviCRM's JS API hung, or an HTTP response code other than 200, which might have similar results).

enter image description here

I see your posted code is PHP not JS, so it may be you aren't using the JS API and can discount the HTTP layer as causing your issues. In that case your next step is probably to inspect the result of the attempted API call, and to investigate error logging (also valid when you are using CiviCRM's HTTP/JS interface).

In that case, inspecting details recorded to the CiviCRM debug log, and your hosting environment's PHP and webserver logs can reveal if there's any indication of an issue there. This question has a detailed writeup on where to find the debug log and other logs, as does the CiviCRM docs.

There's a related question on setting custom data via API which suggests that custom data is not consistently supported by various entity types when modified using the API. That's an old question and might not be up to date.

Hope this is some help!

| improve this answer | |
  • Very helpful, thank you! So looking in the JS Console I'm seeing this error: {"IP":"","level":"security","referer":"","reason":"CSRF suspected","is_error":1,"error_message":"SECURITY ALERT: Ajax requests can only be issued by javascript clients, eg. CRM.api3()."} Why would it be erroring out on a Cross-Site Request Forgery for custom fields and not standard fields? – Jason Bertolacci May 14 '19 at 20:21
  • Looks like you're hitting this code here. I'm not sure why you would not be seeing that header on an API request initiated by CRM.api3, it may be that your webserver doesn't pass the HTTP header X-Requested-With through in $_SERVER['HTTP_X_REQUESTED_WITH']? Perhaps CiviCRM errs in assuming that all PHP configurations will carry that header across, I'm not sure. – Chris Burgess May 14 '19 at 20:59
  • But: If other CRM.api3 calls do work, and this issue is specific to those setting fields via CRM.api3('Contact.create', ['id' => 123, 'custom_1' => 123]), that's peculiar as the code linked in previous comment shouldn't be specific to custom fields. (API code here not tested, just for discussion purposes!) – Chris Burgess May 14 '19 at 21:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.