Help

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

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

Messages, replies, updating or closing a ticket, and webhooks are not part of it. To react to a chat on your own website, see the widget JavaScript API.

Still stuck?

Write to support@retily.com with your support email address and what you tried. Or see all help pages.