Skip to main content

Documentation Index

Fetch the complete documentation index at: https://developers.hubspot.com/docs/llms.txt

Use this file to discover all available pages before exploring further.

The v1 contact lists API was sunset on April 30th, 2026. Calls made to the v1 endpoints will no longer function. Review this guide to understand which endpoints were sunset and to which endpoints you should migrate based on your goal. For complete guidance about using the latest list endpoints, refer to the lists API guide.

Contact list ID migration

Contact lists have two list IDs:
  • legacyListId: the ID used by the v1 lists API.
  • listId: the ID used by the latest version of the lists API.
As a part of migrating to the latest version of the API, you’ll need to update your system to use the listId values instead of legacyListId. For any given list, the value in each field will be different. However, it’s possible that one list’s legacyListId value matches another list’s listId value, so ensure you retrieve all list IDs and compare them carefully to prevent list mapping issues. To retrieve the legacyListId and listId values of each list:
  1. Use the ID mapping endpoint to get the new list IDs for all of the lists in your account.
  2. To prevent data loss in the event of a mistake during migration, store the new list IDs alongside the v1 list IDs.
  3. Once all list IDs have been fetched and stored, migrate to using the List APIs with the new list IDs.
  4. When you’ve fully switched over to using the latest version of the lists API, you can remove the stored v1 list IDs and drop any references to v1 list ID information.

Use the list ID mapping endpoint

To fetch mappings one at a time, make a GET request to /crm/lists/2026-03/idmapping?legacyListId={legacyListId} with the v1 list ID in the legacyListID parameter. Your response will look like:
{
  "listId": "61",
  "legacyListId": "64"
}
To fetch multiple ID mappings in one batch, make a POST request to /crm/lists/2026-03/idmapping and include the legacyListID values within an array, limited to 10,000 entries. For example, your request would look like:
["64", "33", "22566"]
The response would look like:
{
  "missingLegacyListIds": ["22566"],
  "legacyListIdsToIdsMapping": [
    {
      "listId": "61",
      "legacyListId": "64"
    },
    {
      "listId": "38",
      "legacyListId": "33"
    }
  ]
}
You can now use the listId values to refer to lists in the latest list endpoints. The latest version of the lists API is the source of truth, so if a mapping does not exist via the latest API (indicated by the missingLegacyListIds field), it means the list no longer exists.

Impacted endpoints

The following endpoints will return a 404 error as of April 30, 2026. Create, update, and delete contact list endpoints: Retrieve contact list endpoints: Retrieve contacts in a list endpoints: Retrieve contacts with list memberships endpoints: The following endpoints still function, but as of April 30, 2026, no longer return list memberships:
  • Get a contact by visitor ID: GET /contacts/v1/contact/vid/{vid}/profile
  • Get a batch of contacts by visitor ID: GET /contacts/v1/contact/vids/batch
  • Get a contact by email address: GET /contacts/v1/contact/email/{contact_email}/profile
  • Get a batch of contacts by email address: GET /contacts/v1/contact/emails/batch
  • Get a contact by user token: GET /contacts/v1/contact/utk/{contact_utk}/profile
  • Get a batch of contacts by user token: GET /contacts/v1/contact/byUtk/batch

Migrate from v1 to latest list endpoints

If you were previously using any of the v1 list endpoints, you can migrate to the equivalent endpoints, detailed in the sections below.
In the latest endpoint request URLs and request bodies, you must use the new list ID (listId). Using a v1 list ID (legacyListId) for these endpoints may result in updating or deleting the wrong list. Learn more about list ID migration.

Create lists

If you’re using POST /contacts/v1/lists to create lists, migrate to POST /crm/lists/2026-03. In the request body, you must include the following fields: name, objectTypeId, and processingType. Refer to the lists API guide for more information on other fields. You can create lists for objects other than contacts with the latest API, but if your goal is to create a list of contacts, your objectTypeId value must be 0-1. For example:
{
  "name": "My static list",
  "objectTypeId": "0-1",
  "processingType": "MANUAL"
}
When you create a list with the latest endpoint, the listId is returned, which should be the list ID used moving forward.

Update lists

If you’re using POST /contacts/v1/lists/{legacyListId} to update a list, migrate to the following endpoints depending on your goal. To update an active list’s filters, migrate to PUT /crm/lists/2026-03/{listId}/update-list-filters. In your request, include the filterBranch parameter to your request. Learn more about setting up filter branches. To update a list’s name, migrate to PUT /crm/lists/2026-03/{listId}/update-list-name. In your request URL, include the listId of the list and the updated listName. For example: crm/lists/2026-03/12345/update-list-name?listName=New%20list%20name.

Add or remove records in a list

If you’re updating contact list membership using POST /contacts/v1/lists/{legacyListId}/add and POST /contacts/v1/lists/{legacyListId}/remove, migrate to the following endpoints depending on your goal. You can only manually add or remove records in a static list.
  • To add records to a list, migrate to PUT /crm/lists/2026-03/{listId}/memberships/add. Include an array with the id values of records to add.
  • To remove records from a list, migrate to PUT /crm/lists/2026-03/{listId}/memberships/remove. Include an array with the id values of records to remove.
["1234", "5678", "9101"]
To both add and remove records from a list, migrate to PUT /crm/lists/2026-03/{listId}/memberships/add-and-remove. Include the recordsToRemove array with id values of records to remove from the list and the recordsToAdd array with id values of records to add to the list.
{
  "recordIdsToRemove": [654, "321"],
  "recordIdsToAdd": [123, 456, 789]
}

Delete lists

If you’re using DELETE /contacts/v1/lists/{legacyListId} to delete a list, migrate to DELETE /crm/lists/2026-03/{listId}.

Get all static lists

If you’re using GET /contacts/v1/lists/static to get static lists, migrate to POST /crm/lists/2026-03/search. In the request body, include SNAPSHOT and MANUAL in the processingTypes array. Include an additionalProperties array to request that certain list properties are returned.
{
  "offset": 0,
  "count": 100,
  "processingTypes": ["MANUAL", "SNAPSHOT"]
}

Get all active lists

If you’re using GET /contacts/v1/lists/dynamic to get active lists, migrate to POST /crm/lists/2026-03/search. In the request body, include DYNAMIC in the processingTypes array. Include an additionalProperties array to request that certain list properties are returned.
{
  "offset": 0,
  "count": 100,
  "processingTypes": ["DYNAMIC"]
}

Get lists by list ID

If you’re using GET /contacts/v1/lists/{legacyListId} to retrieve individual lists by ID, migrate to GET /crm/lists/2026-03/{listId}. If you’re using GET /contacts/v1/lists/batch to retrieve multiple lists by ID, migrate to GET /crm/lists/2026-03. In the request URL, include listId values. To include filter branches in the response, set the includeListFilters query param to true. For example, your request URL would look like: /crm/lists/2026-03?includeFilters=true&listIds=42&listIds=51. You can also use the search API to filter the lists further, such as by processingType or custom list properties.

Get all members of a list

If you’re using GET /contacts/v1/lists/{legacyListId}/contacts/all to retrieve contacts in a list, migrate to GET /crm/lists/2026-03/{listId}/memberships. Records will be returned in order based on their id values. Your response will look similar to the following:
{
  "results": [
    {
      "recordId": "13161075754",
      "membershipTimestamp": "2025-05-22T16:33:17.864Z"
    },
    {
      "recordId": "13242183272",
      "membershipTimestamp": "2025-05-22T16:33:17.864Z"
    },
    {
      "recordId": "14559658632",
      "membershipTimestamp": "2025-05-22T16:33:17.864Z"
    },
    {
      "recordId": "20903185697",
      "membershipTimestamp": "2025-05-22T16:33:17.864Z"
    },
    {
      "recordId": "20903217801",
      "membershipTimestamp": "2025-05-22T16:33:17.864Z"
    },
    {
      "recordId": "20903639452",
      "membershipTimestamp": "2025-05-22T16:33:17.864Z"
    },
    {
      "recordId": "20903662261",
      "membershipTimestamp": "2025-05-22T16:33:17.864Z"
    },
    {
      "recordId": "20903719953",
      "membershipTimestamp": "2025-05-22T16:33:17.864Z"
    },
    {
      "recordId": "20903752823",
      "membershipTimestamp": "2025-05-22T16:33:17.864Z"
    },
    {
      "recordId": "20903842625",
      "membershipTimestamp": "2025-05-22T16:33:17.864Z"
    }
  ],
  "total": 10
}

Get recent list members

If you’re using GET /contacts/v1/lists/{legacyListId}/contacts/recent to retrieve contacts recently added to a list, migrate to GET /crm/lists/2026-03/{listId}/memberships/join-order. Records will be returned with their id values in the order in which they were added to the list. Your response will look similar to the following:
{
  "results": [
    {
      "recordId": "41720992115",
      "membershipTimestamp": "2025-07-28T13:42:08.595Z"
    },
    {
      "recordId": "79129291921",
      "membershipTimestamp": "2025-01-21T18:06:02.387Z"
    },
    {
      "recordId": "33451",
      "membershipTimestamp": "2023-08-31T16:24:37.296Z"
    }
  ],
  "total": 2
}

Retrieve records with list memberships

If you’re using GET /contacts/v1/lists/all/contacts/all, GET /contacts/v1/lists/recently_updated/contacts/recent, or GET /contacts/v1/lists/all/contacts/recent to retrieve contacts with list memberships, you’ll need to migrate to the latest object and search endpoints. This is because migration for retrieving contacts and their memberships requires two calls: one to retrieve the records, then another to retrieve their list memberships. First, make a POST request to /crm/objects/2026-03/{objectTypeId}/search with the object for which you want to search records (i.e. 0-1 for contacts). You can add filters to specify the records you want.
  • To retrieve recently created records, filter by createdate.
  • To retrieve recently updated records, filter by lastmodifieddate.
You can add properties to retrieve more details about the records as needed. For example, to search for contacts edited after May 31, 2025:
{
  "properties": ["firstname", "lastname", "email", "hs_object_id", "createdate", "lastmodifieddate"],
  "filterGroups": [
    {
      "filters": [
        {
          "propertyName": "lastmodifieddate",
          "operator": "GT",
          "value": "2025-05-31"
        }
      ]
    }
  ]
}
Next, use the object endpoint to retrieve the membership details for the contacts individually or in bulk. From your search request, use record id values to retrieve list membership details. To retrieve an individual record’s memberships, make a GET request to /crm/lists/2026-03/records/{objectTypeId}/{recordId}/memberships. For example, to retrieve a contact’s memberships, your request URL would look like /crm/lists/2026-03/records/0-1/1234567/memberships. Your response will look like:
{
  "results": [
    {
      "listId": "76",
      "listVersion": 1,
      "isPublicList": true,
      "firstAddedTimestamp": "2025-07-28T13:42:08.595Z",
      "lastAddedTimestamp": "2025-07-28T13:42:08.595Z"
    },
    {
      "listId": "78",
      "listVersion": 1,
      "isPublicList": true,
      "firstAddedTimestamp": "2025-07-28T13:42:08.595Z",
      "lastAddedTimestamp": "2025-07-28T13:42:08.595Z"
    },
    {
      "listId": "493",
      "listVersion": 1,
      "isPublicList": false,
      "firstAddedTimestamp": "2024-07-23T19:40:36.192Z",
      "lastAddedTimestamp": "2024-07-23T19:40:36.192Z"
    },
    {
      "listId": "541",
      "listVersion": 1,
      "isPublicList": true,
      "firstAddedTimestamp": "2025-04-21T14:01:43.475Z",
      "lastAddedTimestamp": "2025-04-21T14:01:43.475Z"
    },
    {
      "listId": "492",
      "listVersion": 1,
      "isPublicList": false,
      "firstAddedTimestamp": "2024-07-23T19:36:11.890Z",
      "lastAddedTimestamp": "2024-07-23T19:36:11.890Z"
    }
  ]
}
To retrieve multiple records’ memberships, make a POST request to /crm/lists/2026-03/records/memberships/batch/read. In the request, include the objectTypeId value of the object for which you’re retrieving records (e.g., 0-1 for contacts) and the id values for the records. For example, to retrieve memberships for contacts 12345 and 67890, your request would look like:
{
  "inputs": [
    {
      "objectTypeId": "0-1",
      "recordId": "12345"
    },
    {
      "objectTypeId": "0-1",
      "recordId": "67890"
    }
  ]
}
Last modified on May 5, 2026