In a variety of contexts it is useful to have a Entity Relationship Diagram (ERD) / data-dictionary:

  • Using the API
  • (Xavier avert your eyes) querying the database with SQL
  • Developing extensions; and even
  • Refining the core.

Where is the definitive data-dictionary for CiviCRM? And how do we patch it?

4 Answers 4


You should use the API as the data dictionary. The API explorer (available in every installation) provides a convenient interface to browse the data dictionary.

The demo sites each have an API explorer and they are the authoritative public data dictionary for CiviCRM. For example http://dmaster.demo.civicrm.org/civicrm/api/explorer (login first with username:demo and password:demo). Other versions are also available..

The entity select box shows a list of all available entities. For each entity, the three most important actions from a 'data dictionary' perspective are

  • getfields - for the given entity, this action shows available fields
  • getactions - for the given entity, this action shows available actions
  • getoptions - for the given entity and field this action shows available options (only available for multiple choice fields).

Here are some examples of useful API calls:

To list all entities

civicrm_api3('Entity', 'get');

To list fields for an entity

civicrm_api3('[EntityName]', 'getfields');

To list options for a field (only available for multiple choice fields):

civicrm_api3('[EntityName]', 'getoptions', array( 'field' => "[FieldName]"));

To list actions for an entity:

civicrm_api3('[EntityName]', 'getactions');

FWIW, the above four API functions are used to build the API explorer, which is quite neat, IMO.

As you might expect, in most cases the API is a fairly close match to the database structure. This database structure is defined in a series of XML files that you can find in our git repo (for example this xml file defines the table civicrm_group).

A couple of areas that merit a bit more explanation:

  • Custom data: At the database level, each custom set is a database table and each custom field is a database column. All custom data is registered in two tables civicrm_custom_group and civicrm_custom_field. These tables are exposed in the API as the entities CustomGroup and CustomField.

  • Options: At the database level, a lot of the simple drop-down options that you see in the user interface (for example activity status) are stored in the two tables civicrm_option_value and civicrm_option_group. These are exposed in the API as OptionValue and OptionGroup. The more complex options (for example membership status) typically get their own table and API Entity.

To answer the second question, when you say "patch the data-dictionary", I'm not entirely sure what you mean, but if you were "refining the core" and wanted to for example, add/edit/remove a field, I would

  1. Edit the xml file that creates the database table you are interested in
  2. "Run GenCode.php" to rebuild the data files
  3. Do various other things depending on what you changed!

Of course if you are going down this route, I would recommend discussing any changes with someone who has a deep understanding of CiviCRM and its data structures.


The developer documents on the CiviCRM Wiki are very extensive and cover the codebase and development standards and best practices. There are reference sheets digging into specific areas for the project at hand.

There are XML files on GitHub that describe the database structure and fields.

Your CiviCRM instance should also have an API explorer and generator in civicrm/api/explorer as well as an API parameter list in civicrm/api/doc that are helpful.

  • So which is the definitive source? Mar 25, 2015 at 11:36
  • 1
    The XML files are the definitive source Apr 14, 2015 at 16:10

There is no real data dictionary for CiviCRM. The data in core is generated from some xml schema's which you can find on GitHub at: https://github.com/civicrm/civicrm-core/tree/master/xml/schema

  • I am just upvoting this, simply because down votes are a bit uncool! Mar 25, 2015 at 21:17
  • By the way, Erich if you do access the database directly (and Xavier's eyes are averted) I assume you do use the CRM_Core_DAO::executeQuery method? Apr 2, 2015 at 7:12

I think the best answer it the one that points folk to https://doc.symbiotic.coop/dev/civicrm/latest/schema/index.html which is derived using SchemaSpy per the answer here


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.