Relationships

Learn more about resource relationships available with the JSON API standard.

What are relationships?

Klaviyo’s modern APIs offer powerful new functionality via the relationships object, a thorough set of syntax offered by JSON:API for modeling relationships between resources. This syntax allows developers to efficiently query specific groups of related resources, eliminating the need to perform redundant queries.

Relationships can be to-one or to-many.

Because of the myriad ways our partners and customers model and sync data to and from Klaviyo, the JSON:API relationship syntax used by the new APIs accounts for a wide variety of use cases. Keep in mind that a full relationship mapping may not always be required for all resources.

Scopes

When using relationships, you must use an API key with Read-only (for GET requests) or Full (for GET and POST requests) permissions to both the requested endpoint and its related resource.

For example, to call GET /api/profiles/{profile_id}/?include=lists the scope of your API key must include read access to both the profiles endpoint and the lists endpoint.

Check out the guide to API scopes to learn more about creating and using scopes.

Relationship support

When a relationship between two resources is defined, there are two main ways of querying this relationship: single source and collection-level.

To determine which relationships a specific resource supports, please refer to the endpoint's supported includes values.

Single resource relationship support

Let's use /profiles and /lists as an example. A common use case for many Klaviyo developers is getting all lists a profile belongs to. With the new APIs, this could be accomplished the following ways:

  • GET /api/profiles/{profile_id}/lists
    Get the lists for a single profile directly. Do this if you do not need the profile resource itself, you only need the list.
  • GET /api/profiles/{profile_id}/?include=lists
    Include the lists for a single profile. Do this if you need both the profile resource, and its corresponding lists.
  • GET /api/profiles/{profile_id}/relationships/lists
    Get just the relationship object (the ID mapping) to the corresponding list ID.
    Do this if you only need the list IDs for a profile's lists, and do not need either the profile resource or its corresponding lists.
    This is also the endpoint you can use to create, update or delete relationships, if these operations are supported for the relationship in question.

Example request & response

In this example, we have requested all lists related to the specified profile ID. This request returns the list resources only.

curl --request GET \
     --url 'https://a.klaviyo.com/api/profiles/{profile_id}/lists' \
     --header 'Accept: application/json'
     --header 'Authorization: Klaviyo-API-Key {your-private-api-key}'
     --header 'Revision: YYYY-MM-DD.pre'
{
    "data": [
        {
            "type": "list",
            "id": "V7Raqa",
            "attributes": {
                "name": "Sample Data List",
                "created": "2022-06-15T16:01:12+00:00",
                "updated": "2022-06-15T16:01:12+00:00"
            },
            "links": {
                "self": "https://a.klaviyo.com/api/lists/V7Raqa/"
            }
        }
    ],
    "links": {
        "self": "https://a.klaviyo.com/api/v3/profiles/01G5MDK0GX6K293W4647RNEGXB/lists/",
        "next": null,
        "prev": null
    }
}

Collection-level relationship support

Additionally, certain endpoints support include parameters for top-level GET endpoints. Refer to our API reference documentation for more information on which endpoints support include parameters.

Use include if you need all resources from a particular endpoint (paginated) AND all of their corresponding resources from the relationship.

Example request & response

In this example, we have requested a specific event ID, and have included all profiles related to that event.

curl --request GET \
     --url 'https://a.klaviyo.com/api/v3/events/{event-ID}/?include=profiles' \
     --header 'Accept: application/json'
     --header 'Authorization: Klaviyo-API-Key {your-private-api-key}'
     --header 'Revision: YYYY-MM-DD.pre'
{
    "data": {
        "type": "event",
        "id": "3pAMewFCZAT",
        "attributes": {
            "metric_id": "PQ4zJA",
            "profile_id": "01G5MDK0GX6K293W4647RNEGXB",
            "timestamp": 1655321496,
            "event_properties": {
                "ProductName": "A Tale of Two Cities",
                "ProductID": "1112",
                "Categories": [
                    "Fiction",
                    "Classics"
                ],
                "ImageURL": "http://www.example.com/path/to/product/image.png",
                "URL": "http://www.example.com/path/to/product",
                "Brand": "Harcourt Classics",
                "Price": 19.99,
                "CompareAtPrice": 19.99,
                "$event_id": "sample_data_gen:d3c56774-845a-43fa-a720-632c5e28901c"
            },
            "datetime": "2022-06-15 19:31:36+00:00",
            "uuid": "c5161c00-ece1-11ec-8001-323081228ece"
        },
        "relationships": {
            "profiles": {
                "data": [
                    {
                        "type": "profiles",
                        "id": "01G5MDK0GX6K293W4647RNEGXB"
                    }
                ]
            }
        },
        "links": {
            "self": "https://a.klaviyo.com/api/events/3pAMewFCZAT/"
        }
    },
    "included": [
        {
            "type": "profile",
            "id": "01G5MDK0GX6K293W4647RNEGXB",
            "attributes": {
                "email": "[email protected]",
                "phone_number": null,
                "external_id": null,
                "anonymous_id": null,
                "first_name": "Lindsey",
                "last_name": "Smith (Sample)",
                "organization": "Klaviyo",
                "title": "engineer",
                "image": null,
                "created": "2022-06-15T19:31:34+00:00",
                "updated": "2022-06-15T19:31:36+00:00",
                "last_event_date": "2022-06-15T19:31:36+00:00",
                "location": {
                    "address1": "302 W 3rd St",
                    "address2": "Unit 600",
                    "city": "Cincinnati",
                    "country": "USA",
                    "latitude": null,
                    "longitude": null,
                    "region": "OH",
                    "zip": "45202",
                    "timezone": null
                },
                "properties": {
                    "$latitude": "39.1031",
                    "$longitude": "84.5120",
                    "klaviyo_sample_data_gen": true
                }
            },
            "links": {
                "self": "https://a.klaviyo.com/api/profiles/01G5MDK0GX6K293W4647RNEGXB/"
            }
        }
    ]
}

Modify a relationship

You can not only read relationships, you can also create and delete them.

Create a relationship

To create a new relationship between two resources, make a POST request to the endpoint with the relationship specified in the request body. In this example, we add a profile to a list by sending a POST to that profiles’ list relationship URL, specifying the list ID in the body.

curl --request POST \
     --url 'https://a.klaviyo.com/api/profiles/{profile_id}/relationships/lists' \
     --header 'Accept: application/json'
     --header 'Authorization: Klaviyo-API-Key {your-private-api-key}'
     --header 'Revision: YYYY-MM-DD.pre'
     --data '
{
      "type": "list",
      "id": "{list_id}"
}
’

Delete a relationship

To delete a relationship, make a DELETE request to the endpoint with the relationship specified in the request body. In this example, we are removing the relationship between a profile and the list ID defined in the request body.

curl --request DELETE \
     --url 'https://a.klaviyo.com/api/profiles/{profile_id}/relationships/lists' \
     --header 'Accept: application/json'
     --header 'Authorization: Klaviyo-API-Key {your-private-api-key}'
     --header 'Revision: YYYY-MM-DD.pre'
     --data '
{
      "type": "list",
      "id": "{list_id}"
}
’

Did this page help you?