Contact search API pagination broken?

Hi!

I understand that the new Contacts API is considered stable these days and it introduces a new pagination and sorting system.

Unfortunately, I’m having trouble getting the pagination system to work.

I’m working in a development workspace, and there’s a warning that it’s limited to 20 people, so for testing purposes I’ve set my page size to 2 (which I understand is unusually small).

If I do a search without sorting, e.g:
{
“query”: {
“field”: “role”,
“operator”: “=”,
“value”: “user”
},
“pagination”:
{
“per_page” : 2
}
}

My first response looks reasonable:
{
“type”: “list”,
“data”: [
{
“type”: “contact”,
“id”: “5e767a7f742d596828874e90”,
“workspace_id”: “c2wi3qtr”,

},
{
“type”: “contact”,
“id”: “5e76e5c8b88eb7d2a6dbc1d5”,
“workspace_id”: “c2wi3qtr”,

}
],
“total_count”: 3,
“pages”: {
“type”: “pages”,
“next”: {
“page” => 2,
“starting_after”: “WzAsIjVlNzZlNWM4Yjg4ZWI3ZDJhNmRiYzFkNSIsMl0=”
},
“page”: 1,
“per_page”: 2,
“total_pages”: 2
}
}

However, when I request the next page, e.g:
{
“query”: {
“field”: “role”,
“operator”: “=”,
“value”: “user”
},
“pagination”:
{
“per_page” : 2,
“starting_after”: “WzAsIjVlNzZlNWM4Yjg4ZWI3ZDJhNmRiYzFkNSIsMl0=”
}
}

I get a response that contains the same users even though the pagination data returned claims to be the next (and last) page:
{
“type”: “list”,
“data”: [
{
“type”: “contact”,
“id”: “5e767a7f742d596828874e90”,
“workspace_id”: “c2wi3qtr”,

},
{
“type”: “contact”,
“id”: “5e76e5c8b88eb7d2a6dbc1d5”,
“workspace_id”: “c2wi3qtr”,

}
],
“total_count”: 3,
“pages”: {
“type”: “pages”,
“page”: 2,
“per_page”: 2,
“total_pages”: 2
}
}

It’s also weird to see 2 results on the second page when there are only 3 total matches.

If the request includes sorting, the behavior is slightly different. Let’s try sorting by id:
{
“query”: {
“field”: “role”,
“operator”: “=”,
“value”: “user”
},
“sort”:
{
“field” : “id”
}
“pagination”:
{
“per_page” : 2
}
}

Again, the first result looks reasonable:
{
“type”: “list”,
“data”: [
{
“type”: “contact”,
“id”: “5e76e5dfeecf2264d15aec50”,
“workspace_id”: “c2wi3qtr”,

},
{
“type”: “contact”,
“id”: “5e76e5c8b88eb7d2a6dbc1d5”,
“workspace_id”: “c2wi3qtr”,

}
],
“total_count”: 3,
“pages”: {
“type”: “pages”,
“next”: {
“page” => 2,
“starting_after”: “W251bGwsIjVlNzZlNWM4Yjg4ZWI3ZDJhNmRiYzFkNSIsMl0=”
},
“page”: 1,
“per_page”: 2,
“total_pages”: 2
}
}

But then I request the second page:
{
“query”: {
“field”: “role”,
“operator”: “=”,
“value”: “user”
},
“sort”:
{
“field” : “id”
}
“pagination”:
{
“per_page” : 2,
“starting_after” : “W251bGwsIjVlNzZlNWM4Yjg4ZWI3ZDJhNmRiYzFkNSIsMl0”
}
}

And now my response has no data, the pagination again shows it’s on the second page:
{
“type”: “list”,
“data”: ,
“total_count”: 3,
“pages”: {
“type”: “pages”,
“page”: 2,
“per_page”: 2,
“total_pages”: 2
}
}

What’s going on?

Hey @David_Sickmiller - yeah, we’re aware of the duplicate issues with cursor-based pagination here for Contacts.

We found that the vast majority of cases are caused by what you use to sort. Search is stateless, and the default sorting key is the user’s last request (which can easily change within a single request). This means if that value changes between two subsequent requests, we’ll have duplicates or missing records easily.

Can you specify the sort value to be created_at and see if it helps? More on doing that here.

Zach

@zach I’ve tried paginating over Contacts API with the following base URL:

https://api.intercom.io/contacts?per_page=150&order=ascending&field=created_at

Subsequent pages have the correct starting_after token.

Unfortunately, irrespective of what I do the results after page 10 are all duplicates.

In my case I have 270 contacts, using pagination with per_page = 150 I get 300 records returned when applying pagination… I am not using any sort or anything. Just pure pagination with the following query parameters:

First call has
qs: {per_page: 150}

Second call:
qs: {per_page: 150, starting_after: “WzAsIjVlYjE3YWIwNjMwNTMzOTNhZWI1MTg2ZiIsMl0=”}

Both calls return 150 records so in other words duplicates.

Kind regards,

Louis

1 Like