I'm building a new extension using civix and buildkit. I need to create a new ContactType (sub-type of individual) on install (if it doesn't already exist). I know how I would do it, but I'd prefer to do it in accordance with CiviCRM's standards. What's the correct way to do this?

2 Answers 2


A contact subtype is an "entity" - it exists as a record in the civicrm_contact_type table. So that means you can use the "managed entity" approach described here:


and documented here:


You could instead implement the install hook (https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_install/) and manually test for the existence of the contact type and create it if not (more details in Demerit's answer below).

  • Thank you! I think I'd like to use the managed entity approach and I believe I somewhat understand it. I'm just wondering if there's a civix command to create the .mgd.php file and the code that goes in it, or do I just manually do that? Commented Dec 10, 2019 at 17:29
  • 1
    I believe it's only a manual thing. It's deceptively easy, here's an example: github.com/iATSPayments/com.iatspayments.civicrm/blob/master/… You just have to look at the table and see what CiviCRM expects in terms of fields/types/values.
    – Alan Dixon
    Commented Dec 10, 2019 at 18:05
  • It looks like everything in the managed hook is referencing "version 3". I'm assuming that's api version 3? If so, is it safe to change it to 4 manually? Commented Dec 10, 2019 at 19:11
  • 1
    Good question. Yes, I think you're correct about 3 being the api version. I haven't tried api v4 with the managed hook. I assume it should work similarly.
    – Alan Dixon
    Commented Dec 10, 2019 at 20:08
  • Thanks for all your help! Got it working, but it does not appear that it's possible to use version 4 at this time (at least I can't get it to work. Commented Dec 10, 2019 at 20:57

If you mean which api functions to call to create/update/delete the type, as a general rule you look in api explorer (available via the admin menu in civicrm under Support -> Developer) to see if there's something there (which shows there is ContactType -> create), and if had turned out there wasn't anything you could look in the core code to see how civi does it when you do it from the UI.

If you're asking which hooks to use it would be hook_civicrm_install / uninstall / enable / disable. In install/uninstall you create/delete the type, in enable/disable you set is_active to 1 or 0. In uninstall you might not want to delete the type if there are existing contacts with that type.

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.