Answer tickets from your own system
Your system can answer customers’ tickets without anyone opening the Replyco inbox: for example, to suggest answers generated from your order data, or to reply automatically to questions you can settle on your own. You find the tickets that need an answer, read the conversation, download the customer’s attachments when you need them, and then either leave a draft for an agent to check or send the reply. When the reply settles the question, you can mark the ticket resolved.
Before you start
Section titled “Before you start”| Requirement | Where to get it |
|---|---|
| An access token | Sign in as a Replyco user of your company; see Authentication. |
| Access to the integrations you answer for | The ticket list holds only tickets of the integrations the user you sign in as can access in Replyco. |
| The base URL | https://open-api.replyco.com |
How it works
Section titled “How it works”- Find the tickets to answer.
- Read the conversation.
- Download the customer’s attachments (optional).
- Leave a draft for an agent, or send the reply.
- Mark the ticket resolved (optional).
sequenceDiagram
participant app as Your app
participant api as Replyco API
app->>api: POST /openapi/thread/ticketsforreading/paged
api-->>app: Find the tickets to answer
app->>api: GET /openapi/message/pagedthreadmessages/{threadId}
api-->>app: Read the conversation
opt Download the customer's attachments
app->>api: GET /openapi/bytefiles/messageattachments/{messageId}/links
api-->>app: Download the customer's attachments
end
alt Leave a draft for an agent
app->>api: PUT /openapi/thread/draft/{threadId}
api-->>app: Leave a draft for an agent
else Send the reply
app->>api: POST /openapi/message/send
api-->>app: Send the reply
end
opt Mark the ticket resolved
app->>api: POST /openapi/thread/markresolved
api-->>app: Mark the ticket resolved
end
Step by step
Section titled “Step by step”1. Find the tickets to answer
Section titled “1. Find the tickets to answer”Call POST /openapi/thread/ticketsforreading/paged with a filter. tab picks a list the way the inbox does: 2
holds the tickets that are not resolved yet, 4 the unassigned ones and 1 the ones assigned to you. Use a tab your
user may see in Replyco. accounts narrows the list to some of your integrations, and term searches it.
curl -X POST https://open-api.replyco.com/openapi/thread/ticketsforreading/paged \ -H "Authorization: Bearer $ACCESS_TOKEN" -H "Content-Type: application/json" \ -d '{"page": 1, "count": 50, "tab": 2}'The response is a page: totalRecords, pageSize, pagesCount, currentPage, and the tickets in data, the most
recently active first. Each ticket’s id is the threadId the next steps take. Without count a page holds 10
tickets, and it holds at most 100: a larger count is rejected with 400.
2. Read the conversation
Section titled “2. Read the conversation”Call GET /openapi/message/pagedthreadmessages/{threadId} with a ticket’s id from step 1. Messages come newest
first; send asc=true to read them in the order they were written.
curl "https://open-api.replyco.com/openapi/message/pagedthreadmessages/7d2e9b14-5c3a-4f61-9a8e-2b6c0d4e1f37?count=50" \ -H "Authorization: Bearer $ACCESS_TOKEN"{ "totalRecords": 2, "pageSize": 50, "pagesCount": 1, "currentPage": 1, "data": [ { "id": "4f6b2d81-9e3c-47a5-b2d0-8c1e5a7f3b69", "text": "Hi Jane, sorry to hear that. Could you send us a photo of the parcel?", "messageDate": "2026-10-20T15:12:00Z", "isFromCompany": true }, { "id": "1a9c4e72-3b5d-4e8f-a061-5d7b2c9e8f14", "text": "My parcel arrived damaged. Photo attached.", "messageDate": "2026-10-20T14:05:00Z", "isFromCompany": false } ]}isFromCompany tells your team’s messages (true) from the customer’s. Each message’s id is the messageId step 3
takes.
3. Download the customer’s attachments (optional)
Section titled “3. Download the customer’s attachments (optional)”Skip this step when the text is enough. Call GET /openapi/bytefiles/messageattachments/{messageId}/links for a
message from step 2.
curl https://open-api.replyco.com/openapi/bytefiles/messageattachments/1a9c4e72-3b5d-4e8f-a061-5d7b2c9e8f14/links \ -H "Authorization: Bearer $ACCESS_TOKEN"[ { "fileName": "damaged-parcel.jpg", "url": "https://files.example.com/attachments/damaged-parcel.jpg?signature=abc123", "mimeType": "image/jpeg", "sizeInKiloBytes": 412, "previewId": "c3d7a1e9-5f2b-4c8d-9e6a-0b4f8d2c7a15" }]Download each file with a plain GET to its url, without the Authorization header. A link works for a day, so ask
for fresh links when you need the files instead of storing the links. url is null when no download link is
available, and the list is empty when the message has no attachments.
4. Leave a draft or send the reply
Section titled “4. Leave a draft or send the reply”To leave a draft, call PUT /openapi/thread/draft/{threadId} with the answer as plain text or as htmlBody. When
you send both, htmlBody is used.
curl -X PUT https://open-api.replyco.com/openapi/thread/draft/7d2e9b14-5c3a-4f61-9a8e-2b6c0d4e1f37 \ -H "Authorization: Bearer $ACCESS_TOKEN" -H "Content-Type: application/json" \ -d '{"text": "Hi Jane,\n\nThanks for the photo. We have sent a replacement today."}'{ "text": "Hi Jane,\n\nThanks for the photo. We have sent a replacement today." }To send the reply instead, call POST /openapi/message/send with the ticket’s id and the answer. Replyco sends it on
the ticket’s own integration, so you do not choose the account.
curl -X POST https://open-api.replyco.com/openapi/message/send \ -H "Authorization: Bearer $ACCESS_TOKEN" -H "Content-Type: application/json" \ -d '{"threadId": "7d2e9b14-5c3a-4f61-9a8e-2b6c0d4e1f37", "htmlBody": "<p>Hi Jane,</p><p>We have sent a replacement today.</p>", "text": "Hi Jane,\n\nWe have sent a replacement today."}'{ "threadId": "7d2e9b14-5c3a-4f61-9a8e-2b6c0d4e1f37", "htmlBody": "<p>Hi Jane,</p><p>We have sent a replacement today.</p>", "text": "Hi Jane,\n\nWe have sent a replacement today.", "closeAfterSend": false}Sending a reply also wakes the ticket if it was snoozed and cancels autoresponses still waiting to go out on it.
closeAfterSend: true resolves the ticket in the same call, archiveAfterSend: true archives it, and isDelayed: true
with a sendingDate schedules the reply instead of sending it now. Every call sends a new message, so do not repeat a
call that succeeded.
5. Mark the ticket resolved (optional)
Section titled “5. Mark the ticket resolved (optional)”Skip this step when you sent the reply with closeAfterSend, or when an agent should decide. Otherwise call
POST /openapi/thread/markresolved with the ids of the tickets to resolve.
curl -X POST https://open-api.replyco.com/openapi/thread/markresolved \ -H "Authorization: Bearer $ACCESS_TOKEN" -H "Content-Type: application/json" \ -d '["7d2e9b14-5c3a-4f61-9a8e-2b6c0d4e1f37"]'["7d2e9b14-5c3a-4f61-9a8e-2b6c0d4e1f37"]The tickets move to resolved, and the change is recorded in each ticket’s history. Depending on the signed-in user’s settings in Replyco, the tickets are also unassigned or marked as read.
Choosing between a draft and a reply
Section titled “Choosing between a draft and a reply”| Option | When to pick it | Effect |
|---|---|---|
PUT /openapi/thread/draft/{threadId} |
A person should check the answer first, for example while you tune generated answers. | The draft appears in the reply editor for every agent who opens the ticket. It replaces any earlier draft, is removed when a reply is sent, and is kept for a day. The customer sees nothing. |
POST /openapi/message/send |
The answer is final. | The reply goes to the customer through the ticket’s integration. |
What can go wrong
Section titled “What can go wrong”| Step | Status | Meaning | What to do |
|---|---|---|---|
| any | 401 | The access token is missing or has expired. | Refresh the token; see Authentication. |
| 1 | 400 | count is above 100. |
Ask for 100 tickets or fewer per page. |
| 1, 2 | 429 | Too many calls to this operation. | Slow down; see Rate limits. |
| 3 | 404 | No message with this id. | Use a message id from step 2. |
| 4 | 404 | No ticket with this id (draft). | Use a ticket id from step 1. |
| 4 | 400 | The reply breaks a rule of the ticket’s integration: an attachment is too large, of a blocked type or has no file name, or an eBay reply has no text. |
Read the error text, fix the request and send it again. On eBay tickets, put the reply in text (at most 4000 characters). |
- Ask for at most 100 tickets per page; a larger count is rejected with 400 “Max page size is 100.”
- List operations return 10 items per page unless you send count; send the page size you need instead of paging through small pages.
- 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.
Related
Section titled “Related”- Tickets: filters, states and every ticket operation.
- Messages: reading and sending messages, attachments.
- Attachments: files and their download links.
- Answer live chats: the same flow for live chat.
- API reference: every operation, parameter and schema.