If I do a civicrm_api3('contact', 'getsingle', ['id'=>123]) I get lots of data, including gender.

However when I try to set the gender like:

civicrm_api3('contact', 'create', ['id'=>123, 'gender'=>'Male'])

It reports no error, but neither does it do anything(!).

(Nb. I'm using v4.4.16 LTS)

4 Answers 4


Experimenting with the API explorer, I found that 'gender_id' => 'Male' worked.

  • Do you know if this is a generalised case that works for all such ids (e.g. country_id)? Obvs I can test them one by one, but it would be useful to be able to rely on this behaviour. Jul 31, 2015 at 15:22
  • The latest version of the API explorer should help, as the API should still be fairly consistent between version 4.4 and the latest release at the moment: dmaster.demo.civicrm.org/civicrm/api login demo/demo
    – John
    Jul 31, 2015 at 15:24
  • Thanks, John. Yes the new API explorer is v nice. related question Jul 31, 2015 at 16:09

The field name is gender_id not gender.

For a bit of history and explanation:

The contact api automatically takes a few fields (notably gender_id, prefix_id, suffix_id, state_province_id and a few others) and gives you the label as well as the id for convenience. However this is not consistent across all apis and is not something I would generally rely on.

In v4.4 a lot of work was done to standardize option lists and the upshot is that 'create' type actions will now accept either the id or the name of any option (not the translated label).

So civicrm_api3('contact', 'create', ['id'=>123, 'gender'=>'Male']) and civicrm_api3('contact', 'create', ['id'=>123, 'gender'=>2]) will do the same thing.

Come to think of it, it would be nice to accept either 'gender' or 'gender_id' since that's more consistent with the output. Here's a PR for that.


Try using gender_id when creating the contact, rather than gender.


I solved it by creating a lookup function (which can be used for any field that takes an id that you wouldn't know):

function getIdforLabel($entity, $field, $label) {

    $result = civicrm_api3($entity, 'getoptions', ['sequential' => 1, 'field' => $field]);
    if ($result['is_error']) {
      throw new \Exception("Failed to getoptions for $entity.$field");
    foreach ($result['values'] as $result) {
      if ($result['value'] == $label) {
        return $result['key'];
    throw new \Exception("Supplied value, '$label' is not a valid option.");

So then you can go:

$gender_id = getIdForLabel('contact', 'gender_id', 'Male');
civicrm_api3('contact', 'create', ['id'=>$contact_id, 'gender_id'=>$gender_id]);

Clearly davejenx's answer is simpler :-)

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.