I'm working on converting an app that was built against the REST APIv3 to use REST APIv4, and I've found the APIv4 documentation quite lacking.

Through trial and error, I've determined that Authentication Guard has to be effectively disabled (by having it configured with no options in the Authentication Extension) for CiviCRM to authenticate my call. All other options I've tried return 401 Unauthorized. (Note to others: Make sure you're using a recent version of CiviCRM. While APIv4 has existed for quite some time, the REST part of it appears to have been added around v5.47.)

There are two options that can be enabled, that are not mutually exclusive:

  1. User Permission. What permission is this, and how do you add it?
  2. Site Key. How do you include the Site Key in your APIv4 REST call? The format used for APIv3 does not appear to work.

My question is: How do you leverage Authentication Guard in your APIv4 calls?


1 Answer 1


While the documentation can be confusing, I wouldn't say it's lacking. I want to make sure you found this particular page, particularly the "Guards" section.

In APIv3, you use a site key and an API key. That API key corresponds to a particular user in the database (stored in civicrm_contact table). AuthX adds two new permissions - authenticate with password and authenticate with api key. The "User Permission" guard ensures that only users with one of those permissions can use the APIv4 endpoint. This is almost certainly (one of) the causes of your 401 error.

There are many formats for passing the site key now, too many to effectively answer here. Personally, I put it in the body of a POST request with a key of key, but you should still be able to pass it in as a GET param like in APIv3.

CMS permission settings for AuthX

  • Hi, thanks, I've seen that page many times. No where does it say how or where to add the user permissions it refers to. There's also only one reference to site key, and it's for "legacy rest". Furthermore, the Authentication plugin clearly has two options for Auth Guard: "User Permission" and "Site Key". That is not the same as "with password" and "with API key". Please clarify.
    – Mmm
    Commented Sep 14, 2022 at 12:51
  • @mmm I separated the explanation of "User Permission" and "Site Key" into separate paragraphs - please edit if you think it's unclear! "User Permission" means, "This user has the authenticate with api key permission and I am passing their API key" - or they have authenticate with password and you're passing in a password. It's unrelated to the site key question. The Flows section explains how you can pass the values in - e.g. Authorization: header, X-Civi-Auth: header, etc. Commented Sep 14, 2022 at 13:32
  • This doesn't jive with what I'm seeing. I'm using X-Civi-Auth with an API key for an admin, and it works if I do NOT have Auth Guard enabled. If I add "user permission", I get 401 with the API key. Unless there's a "authenticate with API permission" setting somewhere? I still do not see how to pass the site key anywhere. My original question still stands. What permission is this, and how do you add it? How do you pass the site key?
    – Mmm
    Commented Sep 14, 2022 at 14:04
  • Sorry you're not seeing them - I don't know what CMS you're using but Civi permissions are integrated with the CMS. I added a screenshot of mysite.com/admin/people/permissions on Drupal 7 demonstrating that the permissions are present. If you're using WordPress, I recommend going to Civi's Administer menu » Users and Permissions » Permissions and editing it there, WP's native permission editing sucks without a plugin. Commented Sep 14, 2022 at 15:33
  • 1
    You pass it in as a URL argument with a key of key (works with GET and POST) or as a POST body request with a key of key. Here's a curl statement demonstrating the first approach: curl -X POST https://mysite/civicrm/ajax/rest\?entity\=job\&action\=execute\&key\=<sitekey>\&api_key\=<apikey>\&json\=1\&version\=3 -H 'X-Requested-With: XMLHttpRequest'. You can see an Ansible command that I use to generate a POST request using the second approach here: github.com/MegaphoneJon/ansible-main/blob/… Commented Sep 14, 2022 at 16:09

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.