Skip to content

Tickets

A ticket is one conversation with one customer through one of your integrations: an email thread, a marketplace message thread, a custom integration’s conversation. The API calls tickets threads, so paths and parameters say thread and threadId. Most integrations list tickets to find work, read a ticket’s messages to answer it (see Messages), and then resolve, assign or snooze it.

A ticket in a list has these fields, among others:

Field Meaning
id The ticket’s id. Pass it as threadId to read its messages, set a draft, or change it.
numberId The ticket number your agents see in Replyco.
subject The subject line.
status Where the ticket stands; see States.
accountId, accountName, marketplace The integration the ticket came through.
customerId, customerName, customerEmail The customer.
userId, username The agent the ticket is assigned to; empty when nobody is.
unread, isStarred Whether it has unread messages, and whether it is starred.
snoozeTill Until when the ticket is snoozed; empty when it is not.
createdDate, lastMessageDate When the ticket started, and when its last message arrived or was sent.
orderId, marketOrderId The ticket’s order, when it has one.
priority, respondWithin, resolveWithin The ticket’s priority and its due times; see Priorities and SLAs.
Value State How it gets there
0 Not set A new ticket; or POST /openapi/thread/markunresolved reopens it.
1 Action required Set by an agent in Replyco.
2 In progress Set by an agent in Replyco.
3 Resolved POST /openapi/thread/markresolved.
4 Waiting for customer Set by an agent in Replyco.

Resolving also follows the signed-in user’s settings: it removes the agent when unassignThreadUponResolve is on and marks the ticket read when markAsReadThreadUponResolve is on (see Users). Automatic replies still scheduled for the ticket are cancelled.

Next to its state, a ticket can be:

  • snoozed: POST /openapi/thread/snooze or POST /openapi/thread/snoozethread hide it from the ticket list until the time you give; a null time ends the snooze;
  • starred: POST /openapi/thread/changestarred/{value} with true or false;
  • archived: inActive is true. Archived tickets are left out of the ticket list unless you ask for the archive tab.

POST /openapi/thread/ticketsforreading/paged takes its filters in the request body and returns one page of tickets. It lists only tickets of the integrations and folders the signed-in user has access to; accounts and folders narrow the list further within that.

Field What it does Default Limits
page The page to return. 1 Stop at the response’s pagesCount.
count Tickets per page. 10 At most 100; a larger value is rejected with 400 “Max page size is 100.”
term Searches customer name and email, subject and message text, and matches a ticket number, order number, tracking number or postcode exactly. none —
tab One ticket-list tab: 1 my tickets, 2 not resolved, 4 unassigned, 8 resolved, 64 archive, 256 snoozed, 512 delayed, 1024 starred, 32 blocked customers. The signed-in user must have the tab (ticketListPermission). none: tickets that are not archived, snoozed or from a blocked customer —
folderId Only the tickets in this folder. none —
accounts, folders Only tickets of these integrations or in these folders. all the user can see —
users, searchUnassigned, searchAssignedToMe Only tickets assigned to these agents, unassigned, or assigned to the signed-in user. any agent —
customerId Only this customer’s tickets. any customer —
startDate, endDate Only tickets created in this range (inclusive). no range —
filterTypes, slaTypes Only new, unread, starred… tickets, or tickets due or overdue for a response or resolution. none —
sort lastMessageDate, createdDate, numberId, respondWithin or resolveWithin. lastMessageDate —
asc true for oldest or lowest first. false —
Terminal window
curl -X POST "https://open-api.replyco.com/openapi/thread/ticketsforreading/paged" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d @filter.json
{
"page": 1,
"count": 100,
"searchUnassigned": true,
"startDate": "2026-10-01T00:00:00Z",
"sort": "createdDate",
"asc": true
}

The response holds totalRecords, pageSize, pagesCount, currentPage and the tickets in data. See Answer tickets for a full example.

Other operations list tickets by what they belong to:

Operation Returns
GET /openapi/thread/bycontact/{customerId} A customer’s tickets, newest first, paged with page (default 1) and count (default 10).
GET /openapi/thread/byorder/{orderId} The tickets of an order, archived ones left out.
GET /openapi/thread/byproduct/{productVariationId} Tickets about a product variation or whose order contains it, archived ones left out.
GET /openapi/thread/byfeedback/{feedbackId} The tickets of a review’s order; an empty list when the review has no order.
GET /openapi/thread/simplifiedthread/{id} One ticket, with the fields above.
GET /openapi/thread/parentthread/{id} The ticket another ticket was merged into, when there is one.
GET /openapi/thread/threadscount How many tickets the signed-in user’s list holds, how many are unread, and per-folder counts keyed by folder id.
GET /openapi/thread/unresolvedticketsassignedusers The agents (id, fullName) who have at least one unresolved ticket.

The bulk operations take a JSON array of ticket ids as the body; send at least one id. Resolving, reopening, starring and snoozing set a value, so repeating a request gives the same result.

Operation What it does
POST /openapi/thread/assignuser Assigns the agent in userId to every ticket in threadsIds, replacing the current agent; an empty userId unassigns them. The agent gets a notification unless they are the signed-in user. An unknown user or ticket returns 404; tickets before the unknown one in the list are already assigned.
POST /openapi/thread/markresolved, POST /openapi/thread/markunresolved Resolve or reopen the tickets; see States.
POST /openapi/thread/changestarred/{value} Stars (true) or unstars (false) the tickets.
POST /openapi/thread/snooze, POST /openapi/thread/snoozethread Snooze several tickets (ids, date) or one (threadId, snoozeUntil) until a time in the future; null ends the snooze.
POST /openapi/thread/merge Merges tickets of the same integration and customer. The ticket created first is kept, and the others’ messages, notes and files move into it; the other tickets are deleted. The kept ticket’s subject starts with “MERGED:”.
GET /openapi/thread/assignpriority/{threadId}/{id} Gives the ticket a priority; see Priorities and SLAs.
POST /openapi/thread/removeorder/{threadId} Unlinks the ticket’s order; the order itself stays.
PUT /openapi/thread/draft/{threadId} Saves a draft reply that agents see in the reply editor, as htmlBody or plain text (htmlBody wins when you send both). It replaces the ticket’s draft, is never sent to the customer by itself, and is kept for 24 hours. Send both fields empty to clear it. An unknown ticket returns 404.
POST /openapi/thread/note/{threadId} Adds an internal note that only your team sees, and that never goes to the customer. Send it in note; basic HTML is allowed and cleaned before saving. The user your token stands for becomes the author, and agents who have the ticket open see the note straight away. An empty note returns 400, and an unknown ticket returns 404.
POST /openapi/thread/create Opens a ticket with its first message, on a custom integration only; see Connect your own system.
{
"userId": "0b2d4f6b-8c0e-4a2c-9e4a-6c8e0a2c4e6a",
"threadsIds": [
"7d2e4f6a-8b1c-4d3e-9f5a-6b7c8d9e0f1a",
"8e3f5a7b-9c2d-4e4f-8a6b-7c8d9e0f1a2b"
]
}
{ "note": "Customer called about this order. Refund approved." }
Method Path Summary Scopes
GET /openapi/thread/assignpriority/{threadId}/{id} Assign or remove priority from a thread —
POST /openapi/thread/assignuser Assign or unassign a user to/from multiple threads —
GET /openapi/thread/bycontact/{customerId} Get paginated threads by customer ID —
GET /openapi/thread/byfeedback/{feedbackId} Get all threads associated with a feedback/review —
GET /openapi/thread/byorder/{orderId} Get all threads associated with an order —
GET /openapi/thread/byproduct/{productVariationId} Get all threads associated with a product variation —
POST /openapi/thread/changestarred/{value} Change starred status for multiple threads —
POST /openapi/thread/create Create a new thread (ticket) —
PUT /openapi/thread/draft/{threadId} Set the draft reply for a thread —
POST /openapi/thread/markresolved Mark threads as resolved —
POST /openapi/thread/markunresolved Mark threads as unresolved (reopen) —
POST /openapi/thread/merge Merge multiple threads into one —
POST /openapi/thread/note/{threadId} Add an internal note to a thread (ticket) —
GET /openapi/thread/parentthread/{id} Get parent thread by child thread ID —
POST /openapi/thread/removeorder/{threadId} Remove order association from a thread —
GET /openapi/thread/simplifiedthread/{id} Get simplified thread information by ID —
POST /openapi/thread/snooze Snooze tickets until a specified date —
POST /openapi/thread/snoozethread Snooze a single thread until a specified date —
GET /openapi/thread/threadscount Get total and unread threads count for the current company —
POST /openapi/thread/ticketsforreading/paged Get paginated list of tickets with advanced filtering —
GET /openapi/thread/unresolvedticketsassignedusers Get all users who are assigned to unresolved tickets —
Status Meaning Returned by
400 Invalid request (e.g., empty thread list, too many IDs); Invalid pagination parameters; Invalid request (e.g., empty list, too many IDs); Invalid request - missing required fields, an account that is not a Custom Integration, or an attachment that is too large, of a blocked file type, or missing its file name. The response body carries the reason in its ‘error’ field; Invalid request body; Invalid request (e.g., less than 2 IDs, more than 10 IDs); The note is missing or empty. The response body carries the reason in its ‘error’ field; Invalid request (e.g., past date, too many IDs, invalid date range); Invalid request (e.g., past date, invalid date range); Invalid filter parameters (e.g., page size exceeds 100) POST /openapi/thread/assignuser, GET /openapi/thread/bycontact/{customerId}, POST /openapi/thread/changestarred/{value}, POST /openapi/thread/create, PUT /openapi/thread/draft/{threadId}, POST /openapi/thread/markresolved, POST /openapi/thread/markunresolved, POST /openapi/thread/merge, POST /openapi/thread/note/{threadId}, POST /openapi/thread/snooze, POST /openapi/thread/snoozethread, POST /openapi/thread/ticketsforreading/paged
401 User is not authenticated or authorized GET /openapi/thread/assignpriority/{threadId}/{id}, POST /openapi/thread/assignuser, GET /openapi/thread/bycontact/{customerId}, GET /openapi/thread/byfeedback/{feedbackId}, GET /openapi/thread/byorder/{orderId}, GET /openapi/thread/byproduct/{productVariationId}, POST /openapi/thread/changestarred/{value}, POST /openapi/thread/create, PUT /openapi/thread/draft/{threadId}, POST /openapi/thread/markresolved, POST /openapi/thread/markunresolved, POST /openapi/thread/merge, POST /openapi/thread/note/{threadId}, GET /openapi/thread/parentthread/{id}, POST /openapi/thread/removeorder/{threadId}, GET /openapi/thread/simplifiedthread/{id}, POST /openapi/thread/snooze, POST /openapi/thread/snoozethread, GET /openapi/thread/threadscount, POST /openapi/thread/ticketsforreading/paged, GET /openapi/thread/unresolvedticketsassignedusers
403 User does not have permission to create threads; User does not have access to this thread POST /openapi/thread/create, GET /openapi/thread/simplifiedthread/{id}
404 Thread or priority ID was not found; User ID or one or more thread IDs were not found; Customer with the specified ID was not found; Feedback with the specified ID was not found; Order with the specified ID was not found; Product variation with the specified ID was not found; One or more thread IDs were not found; Thread with the specified ID was not found; Child thread with the specified ID was not found GET /openapi/thread/assignpriority/{threadId}/{id}, POST /openapi/thread/assignuser, GET /openapi/thread/bycontact/{customerId}, GET /openapi/thread/byfeedback/{feedbackId}, GET /openapi/thread/byorder/{orderId}, GET /openapi/thread/byproduct/{productVariationId}, POST /openapi/thread/changestarred/{value}, PUT /openapi/thread/draft/{threadId}, POST /openapi/thread/markresolved, POST /openapi/thread/markunresolved, POST /openapi/thread/merge, POST /openapi/thread/note/{threadId}, GET /openapi/thread/parentthread/{id}, POST /openapi/thread/removeorder/{threadId}, GET /openapi/thread/simplifiedthread/{id}, POST /openapi/thread/snooze, POST /openapi/thread/snoozethread
  • Ask for at most 100 tickets per page; a larger count is rejected with 400 “Max page size is 100.”
  • Setting a ticket’s draft replaces the draft it already has; nothing reaches the customer until an agent sends it.
  • Each paged list operation allows one user 15 calls a minute; ask for larger pages and narrow the list with filters instead of paging through everything.
  • Check the ticket count at most twice a minute for one user.