---
title: Configuring relationships
description: Relationships are references between managed objects. They are defined in your managed object configuration file. You can interact with relationships over REST using the relationship's endpoint, openidm/managed/user/userName/relationshipName?_queryFilter=true.
component: pingidm
version: 8.1
page_id: pingidm:objects-guide:relationships
canonical_url: https://docs.pingidentity.com/pingidm/8.1/objects-guide/relationships.html
keywords: ["Data Object Model", "Relationships", "Roles", "Organizations"]
page_aliases: ["relationships-between-objects.adoc", "view-relationships-over-rest.adoc"]
section_ids:
  example-relationship: "Example relationship: manager"
  retrieve-relationship-data: Retrieve relationship data
  relationship-endpoint-query: Query a relationship endpoint
  relationship-endpoint-read: Read relationship fields
  create-relationship: Create a relationship
  establishing-relationships-between-objects: Creating a relationship as part of a created object
  update-relationship: Update a relationship
  delete-relationship: Delete a relationship
  relationship-properties: Relationship properties
  ref-property: Relationship reference properties
---

# Configuring relationships

Relationships are references between managed objects. They are defined in your managed object configuration *(tooltip: You can edit the managed object configuration over REST at the config/managed endpoint, or directly in the conf/managed.json file.)* file. You can interact with relationships over REST using the relationship's endpoint, `openidm/managed/user/userName/relationshipName?_queryFilter=true`.

Learn more about relationships in:

* [Example relationship: manager](#example-relationship)

* [Relationship properties](#relationship-properties)

Learn more about interacting with relationships over `REST` in:

* [Retrieve relationship data](#retrieve-relationship-data)

* [Create a relationship](#create-relationship)

* [Update a relationship](#update-relationship)

* [Delete a relationship](#delete-relationship)

When modeling relationships, be aware of [bidirectional relationships](reverse-relationships.html) and model them properly in your schema.

[Roles](roles.html) and [Organizations](organizations.html) are implemented using relationships, but you can create relationships between any managed object type.

You can also:

* [Manage relationships using the admin UI](ui-relationships.html).

* Configure IDM to [validate relationships](relationships-validation.html) when they're created.

* Create [custom relationship properties](relationships-custom.html).

* Create [custom relationships](relationships-custom.html).

* Update [relationship-derived vritual properties](managed-object-virtual-properties.html#relationship-derived-virtual-properties) by configuring [relationship change notifications](relationships-notification.html).

* Require the system to [validate relationships](relationships-validation.html) when they're created.

IDM maintains referential integrity by deleting the relationship reference if the object referred to by that relationship is deleted.

## Example relationship: manager

The default configuration includes a relationship named `manager` that lets you configure a relationship between two managed users. This relationship is a good example for understanding how relationships work.

The default `manager` relationship is configured as follows:

```json
"manager" : {
    "type" : "relationship",
    "validate" : true,
    "reverseRelationship" : true,
    "reversePropertyName" : "reports",
    "description" : "Manager",
    "title" : "Manager",
    "viewable" : true,
    "searchable" : false,
    "usageDescription" : "",
    "isPersonal" : false,
    "properties" : {
        "_ref" : {
            "description" : "References a relationship from a managed object",
            "type" : "string"
        },
        "_refProperties" : {
            "description" : "Supports metadata within the relationship",
            "type" : "object",
            "title" : "Manager _refProperties",
            "properties" : {
                "_id" : {
                    "description" : "_refProperties object ID",
                    "type" : "string"
                }
            }
        }
    },
    "resourceCollection" : [
        {
            "path" : "managed/user",
            "label" : "User",
            "query" : {
                "queryFilter" : "true",
                "fields" : [
                    "userName",
                    "givenName",
                    "sn"
                ]
            }
        }
    ],
    "userEditable" : false
},
```

## Retrieve relationship data

There are two ways to retrieve data about a relationship over REST, [querying the relationship endpoint](#relationship-endpoint-query) or [reading relationship fields](#relationship-endpoint-read).

Querying the relationship endpoint supports filtering and paginating the results. It's the safest and most efficient way of retrieving data.

Reading relationship fields does not support filtering or paginating results. To prevent problems that could result from requesting a large amount of data, use this method only in situations where you are certain there are few results.

### Query a relationship endpoint

You can retrieve a managed object's relationship data by querying the relationship endpoint. The endpoint's name is the name of the relationship field.

A relationship endpoint query can use the `_queryFilter` and `_pageSize` parameters to filter and paginate large numbers of results. To avoid the risk of a large query overwhelming your system, use this method whenever possible.

The `_queryFilter` parameter can filter by any fields which are indexed attributes of the related object.

The following example demonstrates querying managed user `bjensen` for all `reports`:

```
curl \
--header "X-OpenIDM-Username: openidm-admin" \
--header "X-OpenIDM-Password: openidm-admin" \
--header "Accept-API-Version: resource=1.0" \
--request GET \
"http://localhost:8080/openidm/managed/user/bjensen/reports?_queryFilter=true"
{
  "result": [
    {
      "_id": "78483e83-9577-40cd-a1d4-6ea0a896e916-4311",
      "_rev": "78483e83-9577-40cd-a1d4-6ea0a896e916-4312",
      "_ref": "managed/user/psmith",
      "_refResourceCollection": "managed/user",
      "_refResourceId": "psmith",
      "_refProperties": {
        "_id": "78483e83-9577-40cd-a1d4-6ea0a896e916-4311",
        "_rev": "78483e83-9577-40cd-a1d4-6ea0a896e916-4312"
      }
    },
    {
      "_id": "78483e83-9577-40cd-a1d4-6ea0a896e916-4934",
      "_rev": "78483e83-9577-40cd-a1d4-6ea0a896e916-4935",
      "_ref": "managed/user/scarter",
      "_refResourceCollection": "managed/user",
      "_refResourceId": "scarter",
      "_refProperties": {
        "_id": "78483e83-9577-40cd-a1d4-6ea0a896e916-4934",
        "_rev": "78483e83-9577-40cd-a1d4-6ea0a896e916-4935"
      }
    }
  ],
  "resultCount": 2,
  "pagedResultsCookie": null,
  "totalPagedResultsPolicy": "NONE",
  "totalPagedResults": -1,
  "remainingPagedResults": -1
}
```

The following example demonstrates querying managed user `bjensen` for all `reports` where the `sn` is Smith:

```
curl \
--header "X-OpenIDM-Username: openidm-admin" \
--header "X-OpenIDM-Password: openidm-admin" \
--header "Accept-API-Version: resource=1.0" \
--request GET \
"http://localhost:8080/openidm/managed/user/bjensen/reports?_queryFilter=sn+eq+'Smith'&_pageSize=1"
{
  "result": [
    {
      "_id": "78483e83-9577-40cd-a1d4-6ea0a896e916-4311",
      "_rev": "78483e83-9577-40cd-a1d4-6ea0a896e916-4312",
      "_ref": "managed/user/psmith",
      "_refResourceCollection": "managed/user",
      "_refResourceId": "psmith",
      "_refProperties": {
        "_id": "78483e83-9577-40cd-a1d4-6ea0a896e916-4311",
        "_rev": "78483e83-9577-40cd-a1d4-6ea0a896e916-4312"
      }
    }
  ],
  "resultCount": 1,
  "pagedResultsCookie": null,
  "totalPagedResultsPolicy": "NONE",
  "totalPagedResults": -1,
  "remainingPagedResults": -1
}
```

You can also pass the `_fields` query parameter to include them in the response, demonstrated here with `userName` and `phoneNumber`:

```
curl \
--header "X-OpenIDM-Username: openidm-admin" \
--header "X-OpenIDM-Password: openidm-admin" \ \
--header "Accept-API-Version: resource=1.0" \
--request GET \
"http://localhost:8080/openidm/managed/user/bjensen/reports?_queryFilter=sn+eq+'Smith'&_fields=userName,phoneNumber&_pageSize=1"
{
  "result" : [ {
    "_id" : "78483e83-9577-40cd-a1d4-6ea0a896e916-45700",
    "_rev" : "78483e83-9577-40cd-a1d4-6ea0a896e916-45701",
    "_ref" : "managed/user/psmith",
    "_refResourceCollection" : "managed/user",
    "_refResourceId" : "psmith",
    "_refResourceRev" : "d776f795-512f-4c09-a673-1f081a8ef3ef-4955",
    "_refProperties" : {
      "_id" : "78483e83-9577-40cd-a1d4-6ea0a896e916-45700",
      "_rev" : "78483e83-9577-40cd-a1d4-6ea0a896e916-45701"
    },
    "userName" : "psmith",
    "phoneNumber" : "0831245986"
  } ],
  "resultCount" : 1,
  "pagedResultsCookie" : null,
  "totalPagedResultsPolicy" : "NONE",
  "totalPagedResults" : -1,
  "remainingPagedResults" : -1
}
```

When you query an endpoint which is a collection, you must use the `_queryFilter` parameter, or you'll receive an error with an `HTTP 400` error code. If you don't want to filter the results, pass `_queryFilter=true`.

Learn more about `_queryFilter` in [Query](../crest/crest-query.html) and [Constructing queries](queries.html#constructing-queries).

### Read relationship fields

To read relationship fields, query a managed object and pass the `_fields` parameter to request associated data fields.

|   |                                                                                                                                            |
| - | ------------------------------------------------------------------------------------------------------------------------------------------ |
|   | Do not use `_fields` to request a field that is a relationship with more than a few members, as this data cannot be filtered or paginated. |

The following example reads a singleton relationship (manager) associated with a managed user (psmith):

```
curl \
--header "X-OpenIDM-Username: openidm-admin" \
--header "X-OpenIDM-Password: openidm-admin" \
--header "Accept-API-Version: resource=1.0" \
--request GET \
"http://localhost:8080/openidm/managed/user/psmith?_fields=manager"
{
  "_id": "0cb7c704-77ab-4211-9f13-04e45847f5e9-17222",
  "_rev": "0cb7c704-77ab-4211-9f13-04e45847f5e9-17223",
  "_ref": "managed/user/bjensen",
  "_refResourceCollection": "managed/user",
  "_refResourceId": "bjensen",
  "_refProperties": {
    "_id": "0cb7c704-77ab-4211-9f13-04e45847f5e9-17222",
    "_rev": "0cb7c704-77ab-4211-9f13-04e45847f5e9-17223"
  }
}
```

When you're reading relationship fields, you can use the managed object endpoint directly using the following syntax:

* `relatedObject/property` (for a simple string value)

* `relatedObject/*/property` (for an array of values)

This example demonstrates retrieving the `mail` and `phoneNumber` properties from psmith's manager using this method:

```
curl \
--header "X-OpenIDM-Username: openidm-admin" \
--header "X-OpenIDM-Password: openidm-admin" \
--header "Accept-API-Version: resource=1.0" \
--request GET \
"http://localhost:8080/openidm/managed/user/psmith?_fields=manager/mail,manager/phoneNumber"
{
  "_id": "psmith",
  "_rev": "0000000014c0b68d",
  "manager": {
    "_rev": "000000005bac8c10",
    "_id": "bjensen",
    "phoneNumber": "12345678",
    "mail": "bjensen@example.com",
    "_ref": "managed/user/bjensen",
    "_refResourceCollection": "managed/user",
    "_refResourceId": "bjensen",
    "_refProperties": {
      "_id": "42418f09-ad6c-4b77-bf80-2a12d0c44678",
      "_rev": "00000000288b921e"
    }
  }
}
```

## Create a relationship

To create a relationship between two managed objects, send a POST request to the relationship's endpoint with a `_ref` parameter containing the path to the other side of the relationship.

For example, suppose the user `psmith` has the user `bjensen` as a manager. The following call creates the `manager` relationship between them:

```
curl \
--header "X-OpenIDM-Username: openidm-admin" \
--header "X-OpenIDM-Password: openidm-admin" \
--header "Accept-API-Version: resource=1.0" \
--header "Content-Type: application/json" \
--request POST \
--data '{
  "_ref" : "managed/user/bjensen"
}' \
"http://localhost:8080/openidm/managed/user/psmith/manager"
{
  "_id": "0cb7c704-77ab-4211-9f13-04e45847f5e9-82148",
  "_rev": "0cb7c704-77ab-4211-9f13-04e45847f5e9-82149",
  "_ref": "managed/user/bjensen",
  "_refResourceCollection": "managed/user",
  "_refResourceId": "bjensen",
  "_refProperties": {
    "_id": "0cb7c704-77ab-4211-9f13-04e45847f5e9-82148",
    "_rev": "0cb7c704-77ab-4211-9f13-04e45847f5e9-82149"
  }
}
```

To learn more about the `_ref` parameter or the relationship reference properties in general, refer to [Relationship properties](#relationship-properties).

### Creating a relationship as part of a created object

In addition to creating a relationship between two existing managed objects, you can create a relationship at the same time as you create a managed object. For example, imagine that you are creating a new user, psmith, and that psmith's manager will be bjensen. You would create psmith's user entry, and *reference* bjensen's entry with the `_ref` property, as follows:

```
curl \
--header "X-OpenIDM-Username: openidm-admin" \
--header "X-OpenIDM-Password: openidm-admin" \
--header "Accept-API-Version: resource=1.0" \
--header "If-None-Match: *" \
--header "Content-Type: application/json" \
--request PUT \
"http://localhost:8080/openidm/managed/user/psmith" \
--data '{
    "_id": "psmith",
    "_rev": "00000000ec41097c",
    "sn": "Smith",
    "userName": "psmith",
    "givenName": "Patricia",
    "displayName": "Patti Smith",
    "description": "psmith - new user",
    "mail": "psmith@example.com",
    "phoneNumber": "0831245986",
    "manager": {
      "_ref": "managed/user/bjensen"
    }
  }'
```

|   |                                                                                                                                                             |
| - | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | Relationship information is not returned by default. To show the relationship in psmith's entry, you must explicitly request her manager entry, as follows: |

```
curl \
--header "X-OpenIDM-Username: openidm-admin" \
--header "X-OpenIDM-Password: openidm-admin" \
--header "Accept-API-Version: resource=1.0" \
--request GET \
"http://localhost:8080/openidm/managed/user/psmith?_fields=manager"
{
  "_id": "psmith",
  "_rev": "00000000ec41097c",
  "manager": {
    "_ref": "managed/user/bjensen",
    "_refResourceCollection": "managed/user",
    "_refResourceId": "bjensen",
    "_refProperties": {
      "_id": "ffc6f0f3-93db-4939-b9eb-1f8389a59a52",
      "_rev": "0000000081aa991a"
    }
  }
}
```

To learn more about the `_ref` parameter or the relationship reference properties in general, refer to [Relationship properties](#relationship-properties).

## Update a relationship

You can update a managed object's relationship data by making a PUT request to its endpoint. The endpoint's name is the name of the relationship field.

When you update a relationship, the related objects automatically update to reflect the new state. In the following example, scarter's `reports` entry is automatically updated when the change to psmith's `manager` entry is updated.

The following example updates psmith's manager to scarter:

```
curl \
--header "X-OpenIDM-Username: openidm-admin" \
--header "X-OpenIDM-Password: openidm-admin" \ \
--header "Accept-API-Version: resource=1.0" \
--header "If-Match: *" \
--header "Content-Type: application/json" \
--request PUT \
--data '{
  "_ref":"managed/user/scarter"
}' \
"http://localhost:8080/openidm/managed/user/psmith/manager"
{
  "_id": "0cb7c704-77ab-4211-9f13-04e45847f5e9-82148",
  "_rev": "0cb7c704-77ab-4211-9f13-04e45847f5e9-108753",
  "_ref": "managed/user/scarter",
  "_refResourceCollection": "managed/user",
  "_refResourceId": "scarter",
  "_refProperties": {
    "_id": "0cb7c704-77ab-4211-9f13-04e45847f5e9-82148",
    "_rev": "0cb7c704-77ab-4211-9f13-04e45847f5e9-108753"
  }
}
```

## Delete a relationship

You can delete a relationship by sending a DELETE request to its endpoint.

The following example deletes psmith's manager:

```
curl \
--header "X-OpenIDM-Username: openidm-admin" \
--header "X-OpenIDM-Password: openidm-admin" \\
--header "Accept-API-Version: resource=1.0" \
--request DELETE \
"http://localhost:8080/openidm/managed/user/psmith/manager"
```

## Relationship properties

Relationships have the following specific configurable properties:

|   |                                                                                                       |
| - | ----------------------------------------------------------------------------------------------------- |
|   | Most of these properties apply to any [managed object type](creating-modifying-managed-objects.html). |

* `type` (string)

  The object type. Must be `relationship` for a relationship object.

* `returnByDefault` (boolean `true, false`)

  Specifies whether the relationship should be returned as part of the response. The `returnByDefault` property is not specific to relationships. This flag applies to all managed object types. However, relationship properties are not returned by default, unless explicitly requested.

* `reverseRelationship` (boolean `true, false`)

  Specifies whether this is a [bidirectional relationship](reverse-relationships.html).

* `reversePropertyName` (string)

  The corresponding property name, in the case of a [bidirectional relationship](reverse-relationships.html). For example, the `manager` property has a `reversePropertyName` of `reports`.

* `resourceCollection` (JSON object)

  The collection of resources (objects) on which this relationship is based (for example, `managed/user` objects).

### Relationship reference properties

When you have defined a relationship, you can use the relationship properties to *reference* one managed user from another. These properties make up a relationship reference:

* `_ref` (JSON object)

  Specifies how the relationship between two managed objects is referenced.

  The value of the `_ref` property is a derived path that is a combination of `_refResourceCollection` and a URL-encoded `_refResourceId`.

* `_refResourceCollection`

  Specifies the container of the referenced object (for example, `managed/user`).

* `_refResourceId`

  Specifies the ID of the referenced object. This is generally a system-generated UUID, such as `9dce06d4-2fc1-4830-a92b-bd35c2f6bcbb`. For clarity, this documentation uses client-assigned IDs such as `bjensen` and `psmith`.

* `_refProperties` (JSON object)

  Any required properties from the relationship that should be included in the managed object. The `_refProperties` field includes a unique ID (`_id`) and the revision (`_rev`) of the object. `_refProperties` can also contain arbitrary fields to support metadata within the relationship.
