Skip to content

APIv4 Implicit Joins

In a relational database, you often need to work with data from multiple entities (tables) at once.

APIv4 provides a simple syntax for automatically reading and writing from entities related by a foreign key:


Example: Get the title of an event's campaign to show to the user



Example: Create an event linked to a campaign without needing to look up the campaign's ID

  ->addValue('', 'My_Cool_Campaign')

These are called implicit because you do not need to tell the API to join tables, it does so automatically by looking at the foreign key of the campaign_id field. For more complex use-cases, an explicit join allows a greater flexibility and control for get actions.

Joins or Chaining

There is some overlap between joins and Chaining; in some cases either technique can accomplish the same thing. Because chaining executes a new query for every result, joins are usually more efficient when given a choice between the two.

Identifying fields eligible for a join

Using getFields with the following params will identify fields that are eligible for an API join, in this example for the Contact entity:

  ->addWhere('fk_entity', 'IS NOT EMPTY')

Multiple joins

Note: multiple joins are only available to get actions

Joining across the same foreign key multiple times:

civicrm_api4('Event', 'get', [
  'select' => ['title', '', 'campaign_id.campaign_type_id'],

Joining multiple levels deep:


Combining a join with an option transformation: