Connect your own system as a custom integration
When customers contact you through a system Replyco has no built-in integration for, such as your own web shop, a customer portal or an in-house messaging channel, you can connect it as a custom integration. Your team then answers those customers in Replyco like any other ticket. You register your system once, and for each conversation you add the customer (and their order, if there is one), open a ticket with the customer’s message, and collect your team’s replies to deliver them to the customer yourself.
Before you start
Section titled “Before you start”| Requirement | Where to get it |
|---|---|
| Open API access and an access token | Replyco support enables the API for your company; you sign in as a Replyco user of your company. See Authentication. |
| A way to deliver replies | Replyco does not call your system. Your integration reads your team’s replies and delivers them to the customer through your own channel. |
| The base URL | https://open-api.replyco.com |
How it works
Section titled “How it works”- Register your system as an integration (once).
- Find your integrations (optional).
- Add the customer.
- Add their order (optional).
- Open a ticket with the customer’s message.
- Collect your team’s replies.
sequenceDiagram
participant app as Your app
participant api as Replyco API
app->>api: POST /openapi/account/addcustomintegration
api-->>app: Register your system as an integration
opt Find your integrations
app->>api: GET /openapi/account/getallcustomintegrations
api-->>app: Find your integrations
end
app->>api: POST /openapi/customer
api-->>app: Add the customer
opt Add their order
app->>api: POST /openapi/order
api-->>app: Add their order
end
app->>api: POST /openapi/thread/create
api-->>app: Open a ticket with the customer's message
app->>api: GET /openapi/message/pagedthreadmessages/{threadId}
api-->>app: Collect your team's replies
Step by step
Section titled “Step by step”1. Register your system as an integration
Section titled “1. Register your system as an integration”Call POST /openapi/account/addcustomintegration once, with the name your team should see in Replyco. The integration
is always created as a custom integration, whatever else you send.
curl -X POST https://open-api.replyco.com/openapi/account/addcustomintegration \ -H "Authorization: Bearer $ACCESS_TOKEN" -H "Content-Type: application/json" \ -d '{"name": "Acme web shop"}'{ "name": "Acme web shop" }"3f1c2a9e-6b4d-4c8e-9f2a-1d5e7b3c9a06"The response is the new integration’s id, as a JSON string. Store it: it is the integrationId of your customers and
orders and the accountId of your tickets. Every call creates another integration, so register once rather than on
every start of your system.
2. Find your integrations (optional)
Section titled “2. Find your integrations (optional)”Skip this step when you stored the id from step 1. Otherwise call GET /openapi/account/getallcustomintegrations; it
lists your company’s custom integrations only, not its marketplace or email integrations.
curl https://open-api.replyco.com/openapi/account/getallcustomintegrations \ -H "Authorization: Bearer $ACCESS_TOKEN"[ { "id": "3f1c2a9e-6b4d-4c8e-9f2a-1d5e7b3c9a06", "name": "Acme web shop" }]To rename an integration, call PUT /openapi/account/updatecustomintegration with its id and every field, because
the call replaces the integration’s settings rather than merging them. DELETE /openapi/account/{id} removes a custom
integration; any other id is answered with 404.
3. Add the customer
Section titled “3. Add the customer”Call POST /openapi/customer with the integration’s id in integrationId, marketplace set to 20 (custom
integration), and what you know about the customer. Put your own id for the customer in marketCustomerId.
curl -X POST https://open-api.replyco.com/openapi/customer \ -H "Authorization: Bearer $ACCESS_TOKEN" -H "Content-Type: application/json" \ -d '{"integrationId": "3f1c2a9e-6b4d-4c8e-9f2a-1d5e7b3c9a06", "marketplace": 20, "firstName": "Jane", "lastName": "Smith", "email": "jane.smith@example.com", "marketCustomerId": "acme-customer-10482"}'The response is the customer as stored. Its id is the customerId the next two steps take.
Every call creates a new customer. When the customer may already exist, look them up first with
GET /openapi/customer/paged?term=acme-customer-10482: term searches names, email, phone and marketCustomerId. See
Look up a customer’s history.
4. Add their order (optional)
Section titled “4. Add their order (optional)”Skip this step when the conversation is not about an order. Otherwise call POST /openapi/order with the integration’s
id, the customer’s id and the order’s details.
curl -X POST https://open-api.replyco.com/openapi/order \ -H "Authorization: Bearer $ACCESS_TOKEN" -H "Content-Type: application/json" \ -d '{"integrationId": "3f1c2a9e-6b4d-4c8e-9f2a-1d5e7b3c9a06", "customerId": "5c8a1e3f-7d2b-4f9c-8e6a-3b1d9f5c7e24", "marketOrderId": "SO-10482", "orderTotalAmount": 89.5, "orderCurrency": "GBP"}'{ "integrationId": "3f1c2a9e-6b4d-4c8e-9f2a-1d5e7b3c9a06", "customerId": "5c8a1e3f-7d2b-4f9c-8e6a-3b1d9f5c7e24", "marketOrderId": "SO-10482", "subject": "1x Walnut desk lamp", "purchaseDate": "2026-10-18T09:30:00Z", "orderTotalAmount": 89.5, "orderCurrency": "GBP", "paid": true, "status": "Shipped", "trackingNumber": "JD000000000000010482"}The order is stored for that customer and integration. See Orders for line items and addresses.
5. Open a ticket with the customer’s message
Section titled “5. Open a ticket with the customer’s message”Call POST /openapi/thread/create with a subject, the integration’s id in accountId, the customer’s id and the
customer’s message. The account must be a custom integration, and the ticket needs its message.
curl -X POST https://open-api.replyco.com/openapi/thread/create \ -H "Authorization: Bearer $ACCESS_TOKEN" -H "Content-Type: application/json" \ -d '{"subject": "Lamp arrived with a broken shade", "accountId": "3f1c2a9e-6b4d-4c8e-9f2a-1d5e7b3c9a06", "customerId": "5c8a1e3f-7d2b-4f9c-8e6a-3b1d9f5c7e24", "message": {"htmlBody": "<p>Hello, the lamp from order SO-10482 arrived with a broken shade.</p>"}}'{ "subject": "Lamp arrived with a broken shade", "accountId": "3f1c2a9e-6b4d-4c8e-9f2a-1d5e7b3c9a06", "customerId": "5c8a1e3f-7d2b-4f9c-8e6a-3b1d9f5c7e24", "message": { "htmlBody": "<p>Hello, the lamp from order SO-10482 arrived with a broken shade.</p>", "attachments": [ { "fileName": "broken-shade.jpg", "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAE=" } ] }}The response is the new ticket. Keep its id: it is the threadId you read replies from in step 6.
- Without
task, the ticket is assigned to the user you sign in as. Sendtask.userIdto assign it to an agent, who is notified. - Without
subject, the ticket is called “No Subject”. - Each attachment needs a
fileNamewith its extension and the file’s content, base64-encoded, indata. A file may be up to 10 MB and the files of one message up to 25 MB together; executable and script files are refused. - Every call opens a new ticket, so do not repeat a call that succeeded.
6. Collect your team’s replies
Section titled “6. Collect your team’s replies”Replyco does not send your team’s replies anywhere. Your integration collects them by reading the ticket’s messages
with GET /openapi/message/pagedthreadmessages/{threadId} and delivers them to the customer itself.
curl "https://open-api.replyco.com/openapi/message/pagedthreadmessages/7d2e9b14-5c3a-4f61-9a8e-2b6c0d4e1f37?count=20" \ -H "Authorization: Bearer $ACCESS_TOKEN"{ "totalRecords": 2, "pageSize": 20, "pagesCount": 1, "currentPage": 1, "data": [ { "id": "4f6b2d81-9e3c-47a5-b2d0-8c1e5a7f3b69", "text": "Hi Jane, sorry about the shade. A replacement is on its way.", "messageDate": "2026-10-20T15:12:00Z", "isFromCompany": true, "userId": "9b3e5f17-2c8d-4a6e-b1f9-7e4d2c6a8b53" }, { "id": "1a9c4e72-3b5d-4e8f-a061-5d7b2c9e8f14", "text": "Hello, the lamp from order SO-10482 arrived with a broken shade.", "messageDate": "2026-10-20T14:05:00Z", "isFromCompany": false } ]}Messages come newest first. Your team’s replies have isFromCompany: true; the customer’s messages do not. Remember
the id of each reply you have delivered, so that the next time you read the ticket you deliver only the new ones.
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. |
| any | 429 | Too many calls to this operation. | Slow down, and read each ticket’s replies less often; see Rate limits. |
| 2 | 404 | The id given to DELETE /openapi/account/{id} is not a custom integration. |
Use an id from GET /openapi/account/getallcustomintegrations. |
| 5 | 400 | accountId is not a custom integration, the request has no message, or an attachment breaks a rule. |
Read the error text. Use the id from step 1 as accountId, include message, and check the attachment rules above. |
- List operations return 10 items per page unless you send count; send the page size you need instead of paging through small pages.
Related
Section titled “Related”- Integrations: every operation on your integrations.
- Customers and Orders: every field you can send.
- Tickets and Messages: reading tickets and their messages.
- Open a ticket for a customer: the same steps for a single ticket.
- Rate limits: how often you can read replies.
- API reference: every operation, parameter and schema.