API
Read your conversations, customers, public knowledge and tickets from your own code, and create customers and tickets. Six endpoints, one API key.
Get an API key
In the app, open Settings › API (under Developer) and click Create key. Give it a name and copy the key: it starts with rtly_ and is shown only once. The Owner and Admins can create keys. Delete a key with its bin icon to revoke it; it stops working at once.
A key works for its own workspace only, and for every endpoint below. Keep it on your server. Never put it in a web page.
Authentication and base URL
Send the key in the X-API-Key header with every request:
X-API-Key: rtly_your_key
Every path below starts with:
https://app.retily.com/api/v1
Answers are JSON. A list comes as {"data": [...]}, one record as {"data": {...}}. The examples are shortened: a record has more fields than shown.
An empty parameter (?status=) is the same as leaving it out. Parameters an endpoint does not list are ignored.
Endpoints
- GET /conversations: List conversations
- GET /customers: List customers
- POST /customers: Create or update a customer
- GET /knowledge: List public knowledge
- GET /tickets: List tickets
- POST /tickets: Create a ticket
GET/conversations
List conversations
Your workspace's conversations, the most recently updated first. Each one comes with its customer and the person it is assigned to. Messages are not included.
Query parameters (all optional)
- statusstring
- OPEN, WAITING, RESOLVED or CLOSED. In capitals.
- limitnumber
- How many to return, a whole number from 1 to 100. Default 50.
There is no page parameter: you get the newest ones, up to the limit.
Example
curl "https://app.retily.com/api/v1/conversations?status=OPEN&limit=20" \ -H "X-API-Key: $RETILY_API_KEY"
{
"data": [
{
"id": "cm2f8x0a1000108l4",
"channel": "CHAT",
"status": "OPEN",
"isAiHandling": true,
"createdAt": "2026-10-17T09:12:44.000Z",
"updatedAt": "2026-10-17T09:15:02.000Z",
"customer": { "id": "cm2f8wz9k000008l4", "name": "Sam Lee", "email": "sam@example.com" },
"assignedTo": null
}
]
}GET/customers
List customers
Your workspace's customers, sorted by lastSeenAt, newest first. Customers with no lastSeenAt (for example, ones created through this API) come first.
Query parameters (all optional)
- searchstring
- Part of a name or an email address. Not case-sensitive.
- limitnumber
- How many to return, a whole number from 1 to 100. Default 50.
Example
curl "https://app.retily.com/api/v1/customers?search=example.com" \ -H "X-API-Key: $RETILY_API_KEY"
{
"data": [
{
"id": "cm2f8wz9k000008l4",
"email": "sam@example.com",
"name": "Sam Lee",
"phone": null,
"metadata": { "plan": "pro" },
"createdAt": "2026-10-02T14:03:10.000Z",
"lastSeenAt": "2026-10-17T09:12:44.000Z"
}
]
}POST/customers
Create or update a customer
Finds the customer with this email address in your workspace and updates them, or creates them. The answer is 201 in both cases.
JSON body
- emailstring, required
- The customer's email address.
- namestring
- Their name. An empty string clears it.
- phonestring
- Their phone number.
- metadataobject
- Your own fields, as a JSON object. Replaces what was there.
Example
curl -X POST "https://app.retily.com/api/v1/customers" \
-H "X-API-Key: $RETILY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"email":"sam@example.com","name":"Sam Lee","metadata":{"plan":"pro"}}'{
"data": {
"id": "cm2f8wz9k000008l4",
"email": "sam@example.com",
"name": "Sam Lee",
"phone": null,
"metadata": { "plan": "pro" }
}
}GET/knowledge
List public knowledge
The knowledge items you marked Public (the ones your public help center can show), the most recently updated first. Draft and Internal items are never returned.
Query parameters (all optional)
- typestring
- ARTICLE, FAQ, RESOLVED_TICKET, CORRECTION or INTERNAL_PROCEDURE. In capitals.
- limitnumber
- How many to return, a whole number from 1 to 100. Default 50.
Each item has only these six fields.
Example
curl "https://app.retily.com/api/v1/knowledge?type=FAQ" \ -H "X-API-Key: $RETILY_API_KEY"
{
"data": [
{
"id": "cm2f90b3c000208l4",
"type": "FAQ",
"title": "Do you ship to Canada?",
"content": "Yes. Orders to Canada arrive in 5 to 8 working days.",
"tags": ["shipping"],
"updatedAt": "2026-10-12T08:30:00.000Z"
}
]
}GET/tickets
List tickets
Your workspace's tickets, the newest first, with their customer and the person they are assigned to. Use page to go further back.
Query parameters (all optional)
- statusstring
- OPEN, IN_PROGRESS, WAITING_CUSTOMER, ON_HOLD, RESOLVED, CLOSED or SPAM. In capitals.
- limitnumber
- How many to return, a whole number from 1 to 100. Default 50.
- pagenumber
- Which page of results, a whole number from 1 to 1,000,000. Default 1.
Example
curl "https://app.retily.com/api/v1/tickets?status=OPEN&page=2" \ -H "X-API-Key: $RETILY_API_KEY"
{
"data": [
{
"id": "cm2f91d7e000308l4",
"ticketNumber": 1042,
"subject": "Refund for order 5521",
"status": "OPEN",
"priority": "MEDIUM",
"source": "API",
"tags": ["refund"],
"createdAt": "2026-10-17T10:01:00.000Z",
"customer": { "id": "cm2f8wz9k000008l4", "name": "Sam Lee", "email": "sam@example.com" },
"assignedTo": null
}
],
"total": 31,
"page": 2,
"limit": 50
}POST/tickets
Create a ticket
Opens a ticket for a customer, found by email address or created. By default the customer gets an email saying the ticket exists, like any ticket your team opens for a customer.
JSON body
- subjectstring, required
- 1 to 500 characters.
- customerEmailstring, required
- The customer's email address.
- customerNamestring
- Used only when the customer is new.
- prioritystring
- LOW, MEDIUM, HIGH or URGENT. Default MEDIUM.
- contentstring
- The customer's message, saved as written by them. Up to 20,000 characters.
- internalNotestring
- A note only your team sees. Up to 20,000 characters.
- notifyCustomerboolean
- Email the customer that the ticket exists. Default true.
- tagsstring[]
- Tags for the ticket.
Up to 60 requests a minute per workspace.
Example
curl -X POST "https://app.retily.com/api/v1/tickets" \
-H "X-API-Key: $RETILY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"subject":"Refund for order 5521","customerEmail":"sam@example.com","content":"My parcel arrived damaged.","priority":"HIGH","tags":["refund"]}'{
"data": {
"id": "cm2f91d7e000308l4",
"ticketNumber": 1043,
"subject": "Refund for order 5521",
"status": "OPEN",
"priority": "HIGH",
"source": "API",
"customer": { "id": "cm2f8wz9k000008l4", "name": "Sam Lee", "email": "sam@example.com" },
"assignedTo": null
}
}Rate limits
POST /tickets takes up to 60 requests a minute per workspace. Past that the answer is 429 with a Retry-After header, in seconds. The other endpoints have no fixed limit today.
Errors
- 400{"error":"Validation failed","message":"limit must be a whole number from 1 to 100.","details":[{"parameter":"limit","message":"limit must be a whole number from 1 to 100."}]}
- A query parameter or body field has a value the endpoint does not accept, a required field is missing, or the body is not a JSON object. details has one entry per problem: parameter names it, message says what it accepts. message joins them.
- 401{"error":"Missing X-API-Key header"}
- The request has no X-API-Key header.
- 401{"error":"Invalid or inactive API key"}
- The key is wrong, or it was revoked.
- 423{"error":"workspace_scheduled_for_deletion", ...}
- The workspace is scheduled for deletion. Every endpoint refuses while it is.
- 429{"error":"Too many requests. Please try again later."}
- More than 60 POST /tickets requests in a minute. Wait the number of seconds in the Retry-After header.
- 500Not always JSON
- Something failed on our side.
Not in the API yet
Still stuck?
Write to support@retily.com with your support email address and what you tried. Or see all help pages.