---
schema_version: "1"
id: c1ecee9981517bf07f9ee996cc2a5bec31ed39d3432401df25822b5b46fccc22
title: Traverse Relationships with Friendly URLs
collection: developer
version: current
locale: en-us
portal_url: https://docs.salesforce.com/developer/current/en-us/platform/api-rest/guides/do-me/dome-relationship-traversal.md
canonical_url: https://developer.salesforce.com/docs/platform/api-rest/guide/dome-relationship-traversal.html
source_site: developer.salesforce.com
content_type: documentation
content_hash: 0f5271df89849a0b87a1e87797f345c5caa80e5f5c6c3c75f7ea3f502568da8c
products:
  - REST API Developer Guide
  - Platform Developer Content
---

# Traverse Relationships with Friendly URLs

You can traverse relationship fields in standard and custom objects by constructing friendly URLs using the sObject Relationship resource. This approach allows you to directly access records associated by relationships. Using friendly URLs is an easier alternative to accessing records by obtaining object IDs from relationship fields and then inspecting the associated object ID record.

**important:** Where possible, we changed noninclusive terms to align with our company value of Equality. We maintained certain terms to avoid any effect on customer implementations.

Relationship names follow certain conventions that depend on the direction (parent to child, or child to parent) of the relationship and the name of the related object. The conventions are described in [Understanding Relationship Names](https://developer.salesforce.com/docs/atlas.en-us.soql_sosl.meta/soql_sosl/sforce_api_calls_soql_relationships_understanding.htm) in the *SOQL and SOSL Reference*.

There are limits to the number of relationship traversals you can make in a single REST API call. These limits are the same as the limits for SOQL, as described in [Understanding Relationship Query Limitations](https://developer.salesforce.com/docs/atlas.en-us.soql_sosl.meta/soql_sosl/sforce_api_calls_soql_relationships_query_limits.htm) in the *SOQL and SOSL Reference*. Keep the following limitations in mind when traversing relationships.

-   When specifying child-to-parent relationships, no more than five levels can be traversed. The following traverses two child-to-parent relationships.

    ```nolang
    https://MyDomainName.my.salesforce.com/services/data/v68.0/sobjects/ChildOfChild__c/record id/Child__r/ParentOfChild__r
    ```

-   When specifying parent-to-child relationships, no more than one level can be traversed. The following traverses one parent-to-child relationship.

    ```nolang
    https://MyDomainName.my.salesforce.com/services/data/v68.0/sobjects/ParentOfChild__c/record id/Child__r
    ```


## Traversing Standard Objects

The standard object Contact contains a relationship field to the Account standard object. The following example retrieves the Account record related to a Contact record.

```nolang
curl https://MyDomainName.my.salesforce.com/services/data/v68.0/sobjects/Contact/0035e00000PiemmAAB/Account -H "Authorization: Bearer token"
```

**Example request body for traversing a standard object relationship:** none required

**Example response body for traversing a standard object simple relationship**

```nolang
{
    "attributes": {
        "type": "Account",
        "url": "/services/data/v68.0/sobjects/Account/0015e00000TwULCAA3"
    },
    "Id": "0015e00000TwULCAA3",
    "IsDeleted": false,
    "Name": "relationshipAccountName",
    "PhotoUrl": "/services/images/photo/0015e00000TwULCAA3",
    "OwnerId": "0055e000003E8ooAAC",
    "CreatedDate": "2021-11-06T17:38:40.000+0000",
    "CreatedById": "0055e000003E8ooAAC",
    "LastModifiedDate": "2021-11-06T17:38:40.000+0000",
    "LastModifiedById": "0055e000003E8ooAAC",
    "SystemModstamp": "2021-11-06T17:38:40.000+0000",
    "LastActivityDate": null,
    "LastViewedDate": "2021-11-06T17:40:50.000+0000",
    "LastReferencedDate": "2021-11-06T17:40:50.000+0000"
}
```

**Example of traversing a simple relationship**

This custom object named Merchandise__c contains a lookup relationship field to a child Distributor__c custom object. The following example retrieves the Distributor__c record related to a Merchandise__c record.

```nolang
curl https://MyDomainName.my.salesforce.com/services/data/v68.0/sobjects/Merchandise__c/a01D000000INjVe/Distributor__r -H "Authorization: Bearer token"
```

**Example request body for traversing a simple relationship:** none required

**Example response body for traversing a simple relationship**

```nolang
{
    "attributes" : 
    { 
        "type" : "Distributor__c",
        "url" : "/services/data/v68.0/sobjects/Distributor__c/a03D0000003DUhcIAG"
    },
    "Id" : "a03D0000003DUhcIAG",
    "OwnerId" : "005D0000001KyEIIA0",
    "IsDeleted" : false,
    "Name" : "Distributor1",
    "CreatedDate" : "2011-12-16T17:43:01.000+0000",
    "CreatedById" : "005D0000001KyEIIA0",
    "LastModifiedDate" : "2011-12-16T17:43:01.000+0000",
    "LastModifiedById" : "005D0000001KyEIIA0",
    "SystemModstamp" : "2011-12-16T17:43:01.000+0000",
    "Location__c" : "San Francisco"
}
```

If no related record is associated with the relationship name, the REST API call fails, because the relationship can’t be traversed. Using the previous example, if the Distributor__c field in the Merchandise__c record was set to `null`, the GET call would return a 404 error response.

You can traverse multiple relationships within the same relationship hierarchy in a single REST API call as long as you don’t exceed the relationship query limits. If a Line_Item__c custom object is the child in a relationship to a Merchandise__c custom object, and Merchandise__c also has a child Distributor__c custom object, you can access the Distributor__c record starting from the Line_Item__c record using something like the following.

```nolang
curl https://MyDomainName.my.salesforce.com/services/data/v68.0/sobjects/Line_Item__c/a02D0000006YL7XIAW/Merchandise__r/Distributor__r -H "Authorization: Bearer token"
```

Relationship traversal also supports PATCH and DELETE methods for relationships that resolve to a single record. Using the PATCH method, you can update the related record.

**Example of using PATCH to update a relationship record**

```nolang
curl https://MyDomainName.my.salesforce.com/services/data/v68.0/sobjects/Merchandise__c/a01D000000INjVe/Distributor__r -H "Authorization: Bearer token"  -d @update_info.json -X PATCH
```

**Example JSON request body for updating a relationship record contained in update_info.json**

```nolang
{
    "Location__c" : "New York"
}
```

**Example response body for updating relationship record:** none returned

Finally, using the DELETE method, you can delete the related record.

**Example using DELETE to delete a relationship record**

```nolang
curl https://MyDomainName.my.salesforce.com/services/data/v68.0/sobjects/Merchandise__c/a01D000000INjVe/Distributor__r -H "Authorization: Bearer token" -X DELETE
```

**Example request body for deleting a relationship record:** none required

**Example response body for update relationship record:** none returned

## Traversing Relationships with Multiple Records

You can traverse relationships with multiple records, and get a response that contains the set of records. For relationships that resolve to multiple records, only GET methods are supported.

**Example traversing a relationship with multiple records**

If we have a custom object named Merchandise__c that contains a master—detail relationship field to a Line_Item__c custom object, the following example retrieves the set of Line_Item__c records related to a Merchandise__c record.

```nolang
curl https://MyDomainName.my.salesforce.com/services/data/v68.0/sobjects/Merchandise__c/a01D000000INjVe/Line_Items__r -H "Authorization: Bearer token"
```

**Example request body for traversing a relationship with multiple records:** none required

**Example response body for traversing a relationship with multiple records**

For this example, two Line_Item__c records were retrieved.

```nolang
{
    "done" : true,
    "totalSize" : 2,
    "records" :
    [
        {
            "attributes" :
            {
                "type" : "Line_Item__c",
                "url" : "/services/data/v68.0/sobjects/Line_Item__c/a02D0000006YL7XIAW"
            },
            "Id" : "a02D0000006YL7XIAW",
            "IsDeleted" : false,
            "Name" : "LineItem1",
            "CreatedDate" : "2011-12-16T17:44:07.000+0000",
            "CreatedById" : "005D0000001KyEIIA0",
            "LastModifiedDate" : "2011-12-16T17:44:07.000+0000",
            "LastModifiedById" : "005D0000001KyEIIA0",
            "SystemModstamp" : "2011-12-16T17:44:07.000+0000",
            "Unit_Price__c" : 9.75,
            "Units_Sold__c" : 10.0,
            "Merchandise__c" : "a00D0000008oLnXIAU",
            "Invoice_Statement__c" : "a01D000000D85hkIAB"
        },
        {
            "attributes" :
            {
                "type" : "Line_Item__c",
                "url" : "/services/data/v68.0/sobjects/Line_Item__c/a02D0000006YL7YIAW"
            },
            "Id" : "a02D0000006YL7YIAW",
            "IsDeleted" : false,
            "Name" : "LineItem2",
            "CreatedDate" : "2011-12-16T18:53:59.000+0000",
            "CreatedById" : "005D0000001KyEIIA0",
            "LastModifiedDate" : "2011-12-16T18:53:59.000+0000",
            "LastModifiedById" : "005D0000001KyEIIA0",
            "SystemModstamp" : "2011-12-16T18:54:00.000+0000",
            "Unit_Price__c" : 8.5,
            "Units_Sold__c" : 8.0,
            "Merchandise__c" : "a00D0000008oLnXIAU",
            "Invoice_Statement__c" : "a01D000000D85hkIAB"
        }
    ]
}
```

The serialized structure for the result data is the same format as result data from executing a SOQL query via REST API. See [Query](https://developer.salesforce.com/docs/platform/api-rest/resources/resources-query.md#query) for more details on executing SOQL queries via REST API

If no related records are associated with the relationship name, the REST API call returns a 200 response with no record data in the response body. This result is in contrast to the results when traversing an empty relationship to a single record, which returns a 404 error response. This behavior is because the single record case resolves to a REST resource that can be used with PATCH or DELETE methods. In contrast, the multiple record case can only be queried.

If an initial GET request for a relationship with multiple records returns only part of the results, the end of the response contains the field `nextRecordsUrl`. For example, you could get a field like the following at the end of your response.

```nolang
"nextRecordsUrl" : "/services/data/v68.0/query/01gD0000002HU6KIAW-2000"
```

You can request the next batch of records using the provided URL with your instance and session information, and repeat until all records have been retrieved. These requests use `nextRecordsUrl` and don’t include any parameters. The final batch of records doesn’t have a `nextRecordsUrl` field.

**Example usage for retrieving the remaining results**

```nolang
curl https://MyDomainName.my.salesforce.com/services/data/v68.0/query/01gD0000002HU6KIAW-2000 -H "Authorization: Bearer token"
```

**Example request body for retrieving the remaining results:** none required

**Example response body for retrieving the remaining results**

```nolang
{
    "done" : true,
    "totalSize" : 3200,
    "records" : [...]
}
```

## Filtering Result Fields

When retrieving records via relationship traversals, you can optionally specify only a subset of the record fields be returned by using the `fields` parameter. Multiple fields are separated by commas. The following example retrieves just the Location__c field from the Distributor__c record associated with a Merchandise__c record:

```nolang
curl https://MyDomainName.my.salesforce.com/services/data/v68.0/sobjects/Merchandise__c/a01D000000INjVe/Distributor__r?fields=Location__c -H "Authorization: Bearer token"
```

The JSON response data would look like the following:

```nolang
{
    "attributes" :
    {
        "type" : "Distributor__c",
        "url" : "/services/data/v68.0/sobjects/Distributor__c/a03D0000003DUhhIAG"
    },
    "Location__c" : "Chicago",
}
```

Similarly, for requests that result in multiple records, you can use a list of fields to specify the fields returned in the record set. For example, assume you have a relationship that was associated with two Line_Item__c records. You want just the Name and Units_Sold__c fields from those records. You could use the following call.

```nolang
curl https://MyDomainName.my.salesforce.com/services/data/v68.0/sobjects/Merchandise__c/a01D000000INjVe/Line_Items__r?fields=Name,Units_Sold__c -H "Authorization: Bearer token"
```

The response data would look like the following.

```nolang
{
    "done" : true,
    "totalSize" : 2,
    "records" : 
    [
        {
            "attributes" :
            {
                "type" : "Line_Item__c",
                "url" : "/services/data/v68.0/sobjects/Line_Item__c/a02D0000006YL7XIAW"
            },
            "Name" : "LineItem1",
            "Units_Sold__c" : 10.0
        },
        {
            "attributes" :
            {
                "type" : "Line_Item__c",
                "url" : "/services/data/v68.0/sobjects/Line_Item__c/a02D0000006YL7YIAW"
            },
            "Name" : "LineItem2",
            "Units_Sold__c" : 8.0
        }
    ]
}
```

If any field listed in the fields parameter set isn’t visible to the active user, the REST API call fails. In the previous example, if the Units_Sold_c field was hidden from the active user by field-level security, the call would return a 400 error response.

