Search Conversations (v3)
Search conversations with a query that combines several conditions. Use the threads resource link inside the Conversation entity to load conversation threads.
Use this endpoint only for filters that List Conversations (v3) cannot express; see Choosing between List and Search.
Request
GET /v3/conversations/search?query=status%3Aactive%20AND%20tag%3A%22VIP%22 HTTP/1.1
Authorization: Bearer oauth_token
The whole search is expressed in the query parameter. It searches specific fields of the conversation (field:value) and combines those conditions with the boolean operators AND, OR and NOT, grouped with parentheses; see Query syntax.
curl "https://api.helpscout.net/v3/conversations/search?query=subject:refund%20AND%20NOT%20tag:processed"
Only conversations in the inboxes you have access to are returned, sorted by conversation id (id) from newest to oldest, which is equivalent to sorting by creation date (createdAt). There is no default status: a query without a status clause matches conversations in every status, including closed and spam. A request with invalid parameters, or a query that can’t be parsed or uses a field or construct not described on this page, is rejected with a 400 Bad Request whose message explains the problem.
Note: If using the embed=threads parameter with this call, you will see truncated chat threads. This is by design. To view Beacon chat threads in full, call the List Threads (v3) endpoint for that conversation instead.
URL Parameters
| Parameter | Type | Examples | Description |
|---|---|---|---|
query |
string |
query=status:active AND tag:"VIP"query=subject:refund AND NOT inboxId:123 |
Search query: field clauses (field:value) combined with AND, OR, NOT and parentheses. Quote values containing spaces. At most 500 characters. The only filter on this endpoint - the typed list filters are not accepted alongside it.See Query syntax and Supported fields |
embed |
enumeration |
embed=threads |
Allows embedding/loading of sub-entities, allowed values are: threads |
cursor |
string |
cursor=eyJpZCI6MTIzfQ== |
Cursor for pagination. See Pagination |
Choosing between List and Search
Start with List Conversations (v3). It covers most filters with typed parameters, and a parameter that takes a comma-separated list matches any of its values, so ?tag=vip,urgent&status=active,pending doesn’t need search. Custom-field filters are only available on List.
Use this endpoint when List can’t express the filter: OR across different fields, NOT, full-text matching on subject or body, or a field List has no parameter for (see Supported fields).
Query syntax
A query is one or more clauses of the form field:value, with no space after the colon. Operators (AND, OR, NOT) are written in uppercase and surrounded by spaces, and parentheses group clauses. Field names and the values of status, type and attachments are case-insensitive.
- Operators have no precedence, so use parentheses whenever a query mixes them:
(NOT status:closed) AND tag:vip,tag:vip AND (status:pending OR status:active). - Always write
ANDexplicitly. Two clauses with no operator between them are joined with anANDthat does not bind the way you might expect. - To match one of several values of the same field, group the values:
status:(active OR pending)is the same as(status:active OR status:pending). - Single-word values do not need quotes:
id:123456,status:closed,tag:vip. Quote a value that is more than one word:tag:"dogs love carrots",subject:"have a question". - To search for a value that contains a character the syntax reserves (
+ - ! ( ) { } [ ] ^ " ~ * ? : \ / & |), quote the value or escape the character with a backslash:tag:\+1. - Every value belongs to a field; a bare value such as
refundon its own is not supported. Wildcards (subject:refund*) and the+/-clause modifiers are not supported either. - A query can nest at most 20 levels deep; each
NOT, and each group whose operator differs from the one around it, adds a level. - URL-encode the query; an HTTP client’s query-parameter encoding does this for you. When building the URL by hand, note that
+must be encoded as%2B, or it is decoded as a space. For more info, see this article.
Supported fields
Only the following fields can be used in a query:
| Field | Value | What it matches |
|---|---|---|
subject |
word or phrase | Conversation subject contains the word or phrase (full text; a phrase matches its words in that order, next to each other) |
body |
word or phrase | Text of the conversation’s threads, notes included, contains the word or phrase (full text, matched like subject). Only about the first 1 MiB of a conversation’s thread text is searchable |
email |
email address | One of the customer’s email addresses (exact) |
contact |
name | Customer’s full name (exact) |
contactId |
number | Customer id |
companyId |
number | Id of the customer’s organization (company) |
tag |
name | Tag name |
tagId |
number | Tag id |
inbox |
name | Inbox name |
inboxId |
number | Inbox id |
assigned |
name | Assignee’s name, or Unassigned for unassigned conversations |
assignedId |
number | Assignee user id |
replyFrom |
name | Name of a user who replied in the conversation |
replyFromId |
number | Id of a user who replied in the conversation |
noteFrom |
name | Name of a user who added a note to the conversation |
noteFromId |
number | Id of a user who added a note to the conversation |
status |
enumeration | Status: active, pending, closed or spam. open is a synonym of active |
type |
enumeration | Type: email, chat, phone, sms, messenger, instagram, whatsapp, slack or ai-answers |
number |
number | Conversation number |
id |
number | Conversation id |
attachments |
true or false |
Whether the conversation has attachments |
createdAt |
date range | Creation date within the range |
modifiedAt |
date range | Last-modified date within the range |
Notes:
- Name fields are matched case-insensitively.
inboxmatches the full inbox name,tagthe tag name with case, spacing and punctuation normalised;assigned,replyFromandnoteFrommatch a user’s full name, first name, last name or @mention name, and a name shared by several users matches all of them. A name that matches nothing simply matches no conversations, soNOT tag:ghostmatches everything. The fields ending inIdtake the id instead and are the more reliable choice for integrations, since a name can change or be shared. - Date fields (
createdAt,modifiedAt) take a range:[lower TO upper]is inclusive and{lower TO upper}exclusive, and the brackets can be mixed. Each bound is a full UTC timestamp such as2024-02-27T00:00:00Z, or*for an open bound:[2024-02-27T00:00:00Z TO *]is everything from that timestamp onwards.
Examples
The queries are shown unencoded for readability; URL-encode them when sending the request.
| Example | What it does |
|---|---|
query=(tag:"vip" AND status:"pending") |
Pending conversations tagged “vip” |
query=(subject:"refund" OR subject:"return") |
Subject contains “refund” or “return” |
query=(assigned:"spock" AND (tag:"vip" OR tag:"urgent")) |
Assigned to Spock and tagged either “vip” or “urgent” |
query=((tag:"vip" OR tag:"urgent") AND NOT status:closed) |
Tagged either “vip” or “urgent”, excluding closed conversations |
query=(inbox:"Orders" AND createdAt:[2024-02-27T00:00:00Z TO *]) |
In the “Orders” inbox and created since 2024-02-27 |
query=(type:chat AND attachments:true AND modifiedAt:[2024-02-01T00:00:00Z TO 2024-03-01T00:00:00Z}) |
Chats with attachments, last modified in February 2024 |
Migrating from v2
If you are migrating a query from the v2 List Conversations endpoint, the clauses and operators look the same, but:
- The field names follow the v3 vocabulary:
mailboxis nowinbox,mailboxidisinboxId,customerIdsiscontactId, andreplyUserIdsisreplyFromId. No space is allowed after the colon. emailmatches the customer’s email addresses only, not theto,ccandbccfields of the messages.- Date bounds are full UTC timestamps; date math such as
NOW-1HOURand partial dates are not supported. - v2 limited a
queryto active conversations unless you sentstatus. This endpoint has no default status, so addAND status:activeto get the same results.
Pagination
This endpoint uses cursor-based pagination. Follow the next link in the response to load the next page of results.
- Each page holds up to 25 conversations; the page size can’t be changed.
- The response
_linkscontainsself,first, and, unless this is the last page,next. - Every link carries the
query, so to page forward, request the URL in_links.next.hrefunchanged. Alternatively, repeat the samequeryandembedand pass the link’scursorvalue in thecursorparameter. - When
_links.nextis absent, there are no more results. - If a cursor is rejected, restart from the first page without one.
- There are no
lastorprevlinks, and nopageobject.
Response
HTTP/1.1 200 OK
Content-Type: application/hal+json
{
"_embedded" : {
"conversations" : [ {
"_links" : {
"self" : {
"href" : "..."
},
"mailbox" : {
"href" : "..."
},
"primaryCustomer" : {
"href" : "..."
},
"createdByUser" : {
"href" : "..."
},
"closedBy" : {
"href" : "..."
},
"threads" : {
"href" : "..."
},
"assignee" : {
"href" : "..."
},
"web" : {
"href" : "..."
}
},
"id" : 10,
"number" : 12,
"threads" : 2,
"type" : "email",
"folderId" : 11,
"status" : "closed",
"state" : "published",
"subject" : "Help",
"preview" : "Preview",
"mailboxId" : 13,
"assignee" : {
"id" : 99,
"type" : "user",
"first" : "Mr",
"last" : "Robot",
"email" : "none@nowhere.com"
},
"createdBy" : {
"id" : 12,
"type" : "system_user",
"email" : "bear@acme.com"
},
"createdAt" : "2012-03-15T22:46:22Z",
"closedBy" : 14,
"closedByUser" : {
"id" : 14,
"type" : "user",
"first" : "Clo",
"last" : "Ser",
"photoUrl" : "pic.jpg",
"email" : "closer@closers.com"
},
"closedAt" : "2012-03-16T14:07:23Z",
"userUpdatedAt" : "2012-03-16T14:07:23Z",
"customerWaitingSince" : {
"time" : "2012-07-24T20:18:33Z",
"friendly" : "20 hours ago"
},
"source" : {
"type" : "email",
"via" : "customer"
},
"tags" : [ {
"id" : 9150,
"color" : "#929499",
"tag" : "vip",
"styles" : {
"dark" : {
"background" : {
"fill" : "#37A4FF"
},
"text" : {
"fill" : "#161616"
}
},
"default" : {
"background" : {
"fill" : "#ACE3FF"
},
"text" : {
"fill" : "#1D2B36"
}
}
}
} ],
"cc" : [ "bear@normal.com" ],
"bcc" : [ "bear@secret.com" ],
"primaryCustomer" : {
"id" : 238604,
"type" : "customer",
"first" : "Rob",
"last" : "Robertovic",
"email" : "rob@acme.com"
},
"snooze" : {
"snoozedBy" : 4,
"snoozedUntil" : "2024-06-03T12:00:00Z",
"unsnoozeOnCustomerReply" : true
},
"nextEvent" : {
"time" : "2024-06-03T12:00:00Z",
"eventType" : "snooze",
"userId" : 4,
"cancelOnCustomerReply" : true
},
"customFields" : [ {
"id" : 8,
"name" : "Account Type",
"value" : "8518",
"text" : "Free"
}, {
"id" : 6688,
"name" : "Account Status",
"value" : "33077",
"text" : "Trial"
}, {
"id" : 9105,
"name" : "ai-topic",
"value" : "41194",
"text" : "Billing",
"systemType" : "topic"
} ],
"_embedded" : {
"threads" : [ ]
}
} ]
},
"_links" : {
"next" : {
"href" : "..."
},
"self" : {
"href" : "..."
},
"first" : {
"href" : "..."
}
}
}
Response fields
| Path | Type | Description |
|---|---|---|
_embedded.conversations |
Array |
Array of Conversation (v3) objects |
_links.self |
Object |
Link to the current page |
_links.first |
Object |
Link to the first page |
_links.next |
Object |
Link to the next page (absent on the last page) |