---
title: "API"
description: "The Retily API: authenticate with a key from Settings › API, list conversations, customers, knowledge and tickets, and create customers and tickets."
url: https://retily.com/help/api
language: en
last_modified: 2026-10-28T18:11:29Z
---

[Help](https://retily.com/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
- 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)

**status string**

OPEN, WAITING, RESOLVED or CLOSED. In capitals.

**limit number**

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)

**search string**

Part of a name or an email address. Not case-sensitive.

**limit number**

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

**email string, required**

The customer's email address.

**name string**

Their name. An empty string clears it.

**phone string**

Their phone number.

**metadata object**

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)

**type string**

ARTICLE, FAQ, RESOLVED_TICKET, CORRECTION or INTERNAL_PROCEDURE. In capitals.

**limit number**

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)

**status string**

OPEN, IN_PROGRESS, WAITING_CUSTOMER, ON_HOLD, RESOLVED, CLOSED or SPAM. In capitals.

**limit number**

How many to return, a whole number from 1 to 100. Default 50.

**page number**

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

**subject string, required**

1 to 500 characters.

**customerEmail string, required**

The customer's email address.

**customerName string**

Used only when the customer is new.

**priority string**

LOW, MEDIUM, HIGH or URGENT. Default MEDIUM.

**content string**

The customer's message, saved as written by them. Up to 20,000 characters.

**internalNote string**

A note only your team sees. Up to 20,000 characters.

**notifyCustomer boolean**

Email the customer that the ticket exists. Default true.

**tags string[]**

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.

**500 Not 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](https://retily.com/docs/widget-js-api).

## Still stuck?

Write to support@retily.com with your support email address and what you tried. Or see [all help pages](https://retily.com/help).
