Payload structure for a response with included resources

Some endpoints support the ability to query for a given type of resource and for related resource types. For example, the default behavior of the GET /activities endpoint is to return only activity resources. However, you can use the include query parameter to include any notes related to the returned activities in the response payload. These types of resources are referred to as included resources. The technique of adding included resources to a GET is sometimes referred to as response inclusion or read inclusion.

The syntax for adding included resources is:

<endpointPath>?include=<resourceName>

where:

  • <endpointPath> is the default path, such as /common/v1/activities
  • <resourceName> is the name of the related resource, such as notes

For example GET /activities?include=notes returns all activities assigned to the current user, and all notes associated with those activities.

You can include multiple resource types in a single query. To do this, identify the resources in a comma-delimited list. For example, GET /policies?include=contacts,locations returns all policies assigned to the current user, and all contacts and locations associated with those policies.

When you execute a call with include, the response payload contains information about the primary resources and the included resources. However, most of the information about the included resources do not appear inline with the primary resources. Rather:

  • Every primary resource has a related section. This section lists the ids (and types) of included resources related to that resource. However, each related section does not include any other details about those resources.
  • Details about the included resources appear at the end of the payload in a section called included.

The ids of included objects appear in both the related section and the included section. You can use these ids to match a primary resource with details about its included resources.

Contrasting included resources and inlined resources

A response payload can contain two types of resources that have a relationship to the root resources: inlined resource and included resources. The following table contrasts the two types of resources.

Resource type How many related resources for each primary resource? Where do their fields appear? When do they appear?
Inlined resource Typically one. (For example, every activity has only one related assignedUser.) Entirely in the attributes section of the root resource If the query does not use the fields query parameter, then each inlined resource appears only if it is one of the default attributes.

If the query does use the fields query parameter, then each inlined resource does or does not appear based on whether it is specified in that query parameter.

Included resource One to many. (For example, every activity can have several related notes.) ids appear in the related section of the root resource. The remaining attributes appear in the included section at the bottom of the payload.

When the query parameter includes the ?include=resourceName query parameter

Tutorial: Send a Postman request with included resources

This tutorial assumes you have set up your environment with Postman and the correct sample data set. For more information, see Tutorial: Set up your Postman environment.

Tutorial steps

  1. In Postman, start a new request by clicking the + to the right of the Launchpad tab.
    1. On the Authorization tab, select Basic Auth using user aapplegate and password gw.
  2. In order to look at a policy in detail, you need to know the policy's public ID. Enter this URL in Postman to retrieve the ID of the first policy, and click Send:

    GET http://localhost:8180/pc/rest/policy/v1/policies?fields=id&pageSize=1

    The ID of the policy is in the response payload at or around line 6. This value is referenced in the next steps as <policyID>.

  3. You can use a GET to retrieve a resource and a set of related resources. For example, in a single GET you can retrieve a policy and all of its contacts. The following GET retrieves the first policy and its contacts. Enter this URL in Postman and click Send:

    GET http://localhost:8180/pc/rest/policy/v1/policies/<policyId>?include=contacts

    Note the following in the response payload:

    • The data section starts at line 2. It includes information about the policy.
    • The included section includes an array of contacts for this policy. The start of the included section depends on the amount of data for the policy. For example, for policy P000143542, the included section starts at line 254.
  4. You can use a GET to retrieve a resource and a single related resource. For example, in a single GET you can retrieve a policy and its primary insured. The following GET retrieves the first policy and its primary insured. Enter this URL in Postman and click Send:

    GET http://localhost:8180/pc/rest/policy/v1/policies/<policyId>?include=primaryInsured

    Note the following in the response payload:

    • The data section starts at line 2. It includes information about the policy. At or around line 35, there is information about the policy's primary insured. However, the only meaningful information is the main contact's display name and ID.
    • The included section includes a single contact for this policy (the primary insured). In this section, there is detailed information about the contact beyond just the display name and ID.

Structure of a response with included resources

The high-level structure of a response with included resources is shown below. Information that pertains specifically to included resources appears in bold. (Note: JSON does not support comments. However, to clarify the code, pseudo-comments have been added. Each pseudo-comment is preceded by a hashtag (#).)

{
    "count": N,                        # Number of resources is payload
    "data": [                          # Details for each resource
        {                              # Resource 1 begins here
            "attributes": {            # Resource 1 name/value pairs
                "propertyName": "propertyValue",
                ... },
            "checksum": "val",         # Resource 1 checksum value
            "links": {                 # Links relevant to Resource 1
                ... },
            "related": {              # List of resources related to R1
                "resourceType": {      # Related resource type
                    "count": NN,       # Number of related resources for R1
                    "data": [
                        {              # First resource related to R1 starts
                            "id": "relatedResourceID",
                            "type": "resourceType"
                        },             # First resource related to R1 ends
                        ...            # Other resources related to R1
                    ] } }
        },                             # Resource 1 ends here
        {                              # Resource 2 begins here
            "attributes": {            # Recourse 2 name/value pairs
                "propertyName": "propertyValue",
                ... },
            "checksum": "val",         # Resource 2 checksum value
            "links": {                 # Links relevant to Resource 2
                ... },
            "related": {               # List of resources related to R2
                "resourceType": {      # Related resource type
                    "count": NN,       # Number of related resources for R2
                    "data": [
                        {              # First resource related to R2 starts
                            "id": "relatedResourceID",
                            "type": "resourceType"
                        },             # First resource related to R2 ends
                        ...            # Other resources related to R2
                    ] } }
        },                             # Resource 2 ends here
        ... ],                         # Resources 3 to N
    "links": {                         # Links relevant to collection
             ...
        },
    "included": {                      # List of related resources
        "resourceType": [              # First related resource type
            {
                "attributes": {        # Related resource 1 start
                    ...                # Related resource 1 name/value pairs
                    "id": " relatedResourceID ",
                    ... },
                "checksum": "0",       # Related resource 1 checksum value
                "links": { ... }       # Links relevant to Related resource 1
            },
            ...                        # Related resources 2 to end
    ] }
}

The related section (for a resource)

For every resource, there is an additional related section that identifies:

  • The number of included resources, and
  • The ids of the included resources

For example, the following code snippet is from the response for a query for all activities and related notes. Activity xc:44 has one included note, whose id is xc:55.

{
    "attributes": {
        ...
        "id": "xc:44",
        ...
        "subject": "Check coverage"
    },
    "checksum": "2",
    "links": {
        ...
    },
    "related": {
        "notes": {
            "count": 1,
            "data": [
                {
                    "id": "xc:55",
                    "type": "Note"
                }
            ]
         }
      }
},

If a GET uses the included query parameter, but no related resources exist, the related section still appears. But, the count is 0 and the data section is empty. For example:

"related": {
    "notes": {
        "count": 0,
        "data": []
    }
}

If a GET omits the included query parameter, the related section is omitted from the response payload.

The included section (for a response)

For every response, there is an included section that appears at the end of the response payload. It lists details about every included resource for the primary resources.

For example, the following code snippet is from the included section from the previous example.

"included": {
    "Note": [
        {
            "attributes": {
                "author": {
                    "displayName": "Betty Baker",
                    "id": "demo_sample:8"
                },
                "bodySummary": "Main contact is on vacation 03/20",
                "confidential": false,
                "createdDate": "2020-03-30T23:11:33.346Z",
                "id": "xc:55",
                "securityType": {
                    "code": "unrestricted",
                    "name": "Unrestricted"
                },
                "subject": "Main contact is on vacation 03/20",
                "topic": {
                    "code": "general",
                    "name": "General"
                },
                "updateTime": "2020-03-30T23:12:08.892Z"
            },
            "checksum": "0",
            "links": {
                "self": {
                    "href": "/common/v1/notes/xc:55",
                    "methods": [
                        "get",
                        "patch"
                    ]
                }
            }
        }
    ]
},

Recall that activity xc:44 has one included note. The included note's id is xc:55. The note shown in the included section is the note related to activity xc:44.

Including either a collection or a specific resource

For a given endpoint, some of the include options return a collection of resources for each primary resource. Other include options return a single resource for each primary resource.

An example of the first case is GET /policies/{policyId}?include=contacts. This call returns the policy with the given Policy ID and all contacts related to that policy. There are theoretically several related resources (contacts) for each primary resource (the policy with the given Policy ID).

An example of the second case is GET /policies/{policyId}?include=primaryInsured. This call returns the policy with the given Policy ID and the contact who is designated as the primary insured. There is only a single related resources (the contact who is the primary insured) for each primary resource (the policy with the given Policy ID).

You can also specify multiple include options, as in GET /policies/{policyId}?include=contacts,primaryInsured. In this case, for each policy, the related section specifies the IDs of all related contacts and it also explicitly identifies the ID of the primary insured.

As a general rule, if an include option is named using a plural, it returns a set of resources for each primary resource. If an include option is named using a singular, it returns a single resource for each primary resource.

Determining which resources can be included

For each endpoint, there are several ways to determine the resources that can be included.

For most endpoints, you can refer to the API definition for the endpoint to find the includable resources. There is a data envelope in the model whose name ends with ...Inclusions. This data envelope lists all the resources that can be included when querying for that type of resource.

For example, in the Common API, the model for GET /activities references an ActivityResponseInclusions element. This element has two child elements: Assignee and Note. This means that the only types of element you can include on an activity query are assignees and notes.

For some endpoints, this method of determining inclusion resources doesn’t work. For example, in the Account API (available in PolicyCenter), the model for GET /accounts references an AccountIncludes element. This element shows many child elements, such as AccountContact. However, if you add ?include=AccountContact to your GET query you’ll receive an error with a message similar to the following:

"userMessage": "Bad value for the 'include' query parameter - The requested inclusions 
'[AccountContact]' are not valid for this resource. The valid options are [accountHolder, 
activities, activity-assignees, activity-patterns, contacts, documents, jobs, locations, notes, 
policies, primaryLocation]."

In cases such as this, the error message will specify which elements are allowed in the include.

Other than creating an error and viewing the results, there are a couple of general rules that can help determine which elements are allowed in an include for a given endpoint: child endpoints and response payload references. (Note that these are general guidelines, and don’t necessarily apply in all cases.)

Child endpoints

Suppose you have the following set of endpoints:

  • /api/v1/endpoint
  • /api/v1/endpoint/child1
  • /api/v1/endpoint/child1/child2

In most cases, you can include child2 on any calls to endpoint or endpoint/child1:

GET /api/v1/endpoint?include=child2
GET /api/v1/endpoint/child1?include=child2

Response payload references

Suppose once again that you have the following endpoint:

  • /api/v1/endpoint

Doing a GET on this endpoint returns the following response:

{
  "data": {
    "attributes": {
      "foreignKeyEntity" {
        "id": "100"
      }
    }
  }
}

In many cases such as this you can do an include that specifies the returned attribute (or attributes, if there are more than one):

GET /api/v1/endpoint?include=foreignKeyEntity