I need to add an entityRef lookup field to a public facing profile form so that users can search and select organization contacts. I patterned it after the current employer lookup in the contact record with slight changes (you can't create a new contact):

$props = array(
  'api' => array('params' => array(
    'contact_type' => 'Organization',
    'check_permissions' => 0,
$form->addEntityRef('employer_id', ts('Organization'), $props);

If I access the form anonymously, the lookup fails with a permission error. If I grant the public user "access AJAX API" it does not fail, but does not return any records (because the public user isn't permissioned to view all contacts). You'll see that I attempted to modify the API with check_permissions, but it has no impact.

With "access AJAX API" enabled for the public user, the alterAPIPermissions hook is hit -- so I could modify the perms and avoid granting the public user "view all contacts" permission.

My question is: What are the consequences of giving the public user access AJAX API permission? Is there some way to avoid having to do that? Is the above the right way to implement this -- to grant that permission and them modify the actual permissions with the hook?

EDIT: Actually, I don't seem to be able to grant sufficient permissions with alterAPIPermissions. I've tried:

$params['check_permissions'] = 0;
$permissions['contact']['get'] = array('profile create');
$permissions['contact']['getquick'] = array('profile create');

(the anonymous user has profile create permission) and the entityRef still returns no records.

  • 1
    FYI The reason changing $params['check_permissions'] to false doesn't work is because these params are then sent to the server from the javascript widget, and for good reasons, the server will not trust rest requests attempting to disable permission checks.
    – Coleman
    Commented Dec 22, 2015 at 16:55

2 Answers 2


The Access AJAX API permission was added in CRM-8840 to get around the firewall of sorts that surrounds the API unless you have Access CiviCRM. If you don't have either, you'll get blocked trying any Javascript call to the API, regardless of your other permissions (whether granted via hook, ACLs, or CMS).

As best I know (and I just did a quick test on a dummy site), all of the APIs require Access CiviCRM or Administer CiviCRM even beside the blanket requirement for Access CiviCRM or Access AJAX API. While adding Access AJAX API will get your foot in the proverbial door, you won't have the ability to do anything. You'll want to write a hook to change the permissions in the specific cases that you need to run an API call.

So yes, you're on the right track, and no, there shouldn't be any immediate negative consequences of adding Access AJAX API. However, since it removes the outer layer of security against the API, you'll just need to be sure everything's configured tightly.

  • Modifying the permissions via the hook doesn't work, unfortunately (see my edit to the original description). Commented Dec 21, 2015 at 21:28
  • Yeah, that could be a number of things. When using that hook, I generally have to experiment a bit with it. You might break down your problem by using straight API calls through the Firebug console like CRM.api3('Contact', 'get'); and see what returns. Once you have that working to your liking, you can see if the problem is in your API permissions or something specific to the entityRef.
    – Andie Hunt
    Commented Dec 21, 2015 at 22:01

I wonder if a better pattern to start with would be custom fields of type "ContactReference" - these go through a different ajax callback which by default does not check permissions (for better or worse).

  • Just seems like a shame to have to build a workaround like that. In this case, I simply want the current employer field to be a searchable/lookup list for anonymous users. Because the form process already looks for the employer_id field, you simply need to add the field to the form -- no postProcess work required. But if I have to create a custom field, I then need to process that against the native field. It just seems like we should be able to modify the permissions more easily than this. Commented Dec 21, 2015 at 21:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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