Search conversations
Search your account's conversations by contact name, phone number and message text in one call. It is the same search your team uses from the search box of the live chat, and it returns two groups of results:
contacts: the conversations whose contact name or phone number matches the term, one result per contact. The top matches are returned, not paginated.messages: the individual messages whose text matches the term, newest first, paginated.
Each result carries the session_key of its conversation, so you can pass it straight to the other Conversations endpoints, or fetch the messages of that conversation.
Endpointβ
GET https://api.p.2chat.io/open/search
Authenticationβ
Include your API key in the X-User-API-Key header. Learn more about authentication.
API costβ
Each call to this endpoint deducts 5 API credits from your plan's API credit pool.
This endpoint runs the contact search and the message search over the whole account in one call, so it costs more than the usual 1 credit of other /open/ endpoints.
Permissionsβ
The search runs as the user who owns the API key, with the same visibility as in the live chat. An admin searches every conversation of the account. Any other user only finds conversations they can open: those of a number shared with them, or those assigned to them or to one of their teams.
Parametersβ
These parameters are sent as query string parameters.
| Field | Type | Required | Description |
|---|---|---|---|
q | string | Yes | The search term, at least 2 characters. Matched against the contact's name, their phone number and the text of the messages. Examples: Kate, 5550147, invoice |
page_number | integer | No | Zero-based page of the messages group. Defaults to 0. The contacts group is not paginated |
results_per_page | integer | No | Messages returned per page, between 1 and 100. Defaults to 20 |
contacts_limit | integer | No | Maximum number of contact matches returned, between 1 and 50. Defaults to 20 |
How matching worksβ
- Contact names are matched by word and by partial text, ignoring accents:
josefindsJosΓ© PΓ©rez, andCarlfindsCarlos. - Phone numbers are matched on their digits. Any run of digits finds the numbers that contain it:
5550147finds+14085550147. - Message text is matched by word, ignoring accents. Each message result includes a
highlightwith the fragment of the text where the term was found, the term wrapped in<em>tags. - Results come from the search index. A message received a few seconds ago may not appear yet.
Invocationβ
- cURL
- Python
- JavaScript
- PHP
curl --location 'https://api.p.2chat.io/open/search?q=invoice&page_number=0&results_per_page=20&contacts_limit=20' \
--header 'X-User-API-Key: your_api_key_here'
import requests
url = "https://api.p.2chat.io/open/search"
headers = {
"X-User-API-Key": "your_api_key_here"
}
params = {
"q": "invoice",
"page_number": 0,
"results_per_page": 20,
"contacts_limit": 20
}
response = requests.get(url, headers=headers, params=params)
print(response.json())
const axios = require('axios');
const response = await axios.get('https://api.p.2chat.io/open/search', {
params: {
q: 'invoice',
page_number: 0,
results_per_page: 20,
contacts_limit: 20
},
headers: {
'X-User-API-Key': 'your_api_key_here'
}
});
console.log(response.data);
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://api.p.2chat.io/open/search?' . http_build_query([
'q' => 'invoice',
'page_number' => 0,
'results_per_page' => 20,
'contacts_limit' => 20
]),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => array(
'X-User-API-Key: your_api_key_here'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
Responseβ
Success (HTTP 200 OK)β
{
"success": true,
"query": "invoice",
"contacts": {
"count": 1,
"results": [
{
"contact_uuid": "CON8c1f4e2a-7b3d-4f0e-9a61-2d5c8e7f1b93",
"contact_name": "Invoice Desk Β· Acme",
"phone_number": "+14085550176",
"session_key": "WA-WAN8fd3442f-e111-4fed-9323-1824fd7546c9-14085550176",
"channel_uuid": "WAN8fd3442f-e111-4fed-9323-1824fd7546c9",
"last_message_at": "2026-11-09T18:20:00Z"
}
]
},
"messages": {
"count": 2,
"page": 0,
"results_per_page": 20,
"results": [
{
"message_uuid": "MSG5e2d9c41-7a3f-4b8e-9c01-6d2f8a4b7e13",
"session_key": "WP-WPN3a9e7c15-2f84-4b6d-8e01-c7d2f9a4b5e6-5491155550123",
"channel_uuid": "WPN3a9e7c15-2f84-4b6d-8e01-c7d2f9a4b5e6",
"contact_uuid": "CONd27b0a95-41c6-4e8f-b3a2-6f1e9c0d7a48",
"contact_name": "Katerina",
"phone_number": "+5491155550123",
"text": "Could you resend the invoice for October?",
"highlight": {
"text": ["Could you resend the <em>invoice</em> for October?"]
},
"direction": "inbound",
"sent_at": "2026-11-08T13:05:42Z"
},
{
"message_uuid": "MSGa1b7c3d9-2e4f-4a6b-8c0d-1e3f5a7b9c2d",
"session_key": "WA-WAN8fd3442f-e111-4fed-9323-1824fd7546c9-14085550176",
"channel_uuid": "WAN8fd3442f-e111-4fed-9323-1824fd7546c9",
"contact_uuid": "CON8c1f4e2a-7b3d-4f0e-9a61-2d5c8e7f1b93",
"contact_name": "Invoice Desk Β· Acme",
"phone_number": "+14085550176",
"text": "Your invoice is attached. Thanks!",
"highlight": {
"text": ["Your <em>invoice</em> is attached. Thanks!"]
},
"direction": "outbound",
"sent_at": "2026-11-02T09:41:10Z"
}
]
}
}
| Field | Description |
|---|---|
success | true when the request was successful |
query | The search term, as it was searched |
contacts.count | Total number of conversations whose contact matched, across the whole account |
contacts.results | The top contacts_limit matches, best match first |
contacts.results[].contact_uuid | UUID of the contact, or null when the conversation has no contact in your account |
contacts.results[].contact_name | The contact's name as shown in the live chat |
contacts.results[].phone_number | The contact's phone number |
contacts.results[].session_key | The conversation. Use it with the other Conversations endpoints |
contacts.results[].channel_uuid | UUID of the connected number the conversation belongs to |
contacts.results[].last_message_at | When the most recent matching message of that conversation was sent, in UTC |
messages.count | Total number of messages matching the term, across all pages |
messages.page | The zero-based page returned, echoing page_number |
messages.results_per_page | The page size used |
messages.results | The messages on this page, newest first |
messages.results[].message_uuid | UUID of the message |
messages.results[].session_key, channel_uuid, contact_uuid, contact_name, phone_number | The conversation and contact the message belongs to, as in the contacts group |
messages.results[].text | The text of the message |
messages.results[].highlight | The fragment(s) of the text where the term matched, with the term wrapped in <em> tags |
messages.results[].direction | inbound when the contact sent it, outbound when your account did |
messages.results[].sent_at | When the message was sent, in UTC |
Errorβ
{
"success": false,
"error": true,
"error_message": "Please upgrade your account to continue using this API: You have exceeded the API quota for your plan."
}
| Field | Description |
|---|---|
error | true when the request failed |
error_message | A description of what went wrong |
| HTTP status | When |
|---|---|
422 | q is missing or shorter than 2 characters, or a paging parameter is out of its range. Nothing is billed |
402 | Your account has no API credits left. Nothing is searched |
401 | The API key is missing or invalid |