REST API Reference
Reference for core REST API endpoints. For the full list, use the OpenAPI spec.
Base URL
https://your-domain.com/api/v1
Authentication
All requests require authentication:
Authorization: Bearer YOUR_API_KEY
OpenAPI spec: https://your-domain.com/openapi.json
Tickets
List Tickets
GET /tickets
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
| status | string | Filter by status |
| priority | string | Filter by priority |
| assignee_id | string | Filter by assignee |
| customer_id | string | Filter by customer |
| unassigned | boolean | Show only unassigned tickets |
| tags | string | Comma-separated tag list |
| search | string | Search subject and summary |
| order_by | string | Sort field (e.g., created_at) |
| order_dir | string | Sort direction (asc or desc) |
| limit | integer | Items per page (max 100) |
| cursor | string | Cursor for pagination (ISO timestamp) |
Example:
curl -H "Authorization: Bearer API_KEY" \
"https://your-domain.com/api/v1/tickets?status=open&limit=25"
Response:
{
"data": [
{
"id": "tkt_123",
"subject": "Help needed",
"status": "open",
"priority": "medium",
"customer": {
"id": "cust_456",
"email": "user@example.com"
},
"assignee": null,
"tags": ["support"],
"created_at": "2025-01-15T10:30:00Z",
"updated_at": "2025-01-15T10:30:00Z"
}
],
"meta": {
"limit": 25,
"total": 150,
"next_cursor": "2025-01-15T10:30:00Z"
}
}
Get Ticket
GET /tickets/{id}
Response:
{
"data": {
"id": "tkt_123",
"subject": "Help needed",
"status": "open",
"priority": "medium",
"description": "Full ticket description...",
"customer": { ... },
"assignee": { ... },
"tags": ["support"],
"custom_fields": {},
"created_at": "2025-01-15T10:30:00Z",
"updated_at": "2025-01-15T10:30:00Z"
}
}
Create Ticket
POST /tickets
Body:
{
"subject": "Help needed",
"description": "Detailed description of the issue",
"customer_email": "user@example.com",
"priority": "medium",
"tags": ["support"]
}
Response: Created ticket object
Update Ticket
PATCH /tickets/{id}
Body:
{
"status": "pending",
"priority": "high",
"assignee_id": "user_789"
}
Delete Ticket
DELETE /tickets/{id}
Conversations
List Conversations
GET /conversations
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
| ticket_id | string | Filter by ticket ID |
| type | string | Filter by type (reply, note, system) |
| internal | boolean | Filter internal notes |
| limit | integer | Items per page (max 100) |
| cursor | string | Cursor for pagination (ISO timestamp) |
Response:
{
"data": [
{
"id": "conv_123",
"ticket_id": "tkt_123",
"type": "reply",
"internal": false,
"content_text": "Message content",
"created_at": "2025-01-15T10:30:00Z"
}
],
"meta": {
"limit": 50,
"total": 150,
"next_cursor": "2025-01-15T10:30:00Z"
}
}
Create Conversation
POST /conversations
Body:
{
"ticket_id": "tkt_123",
"content": "Thank you for reaching out...",
"type": "reply",
"internal": false
}
Use internal: true for private notes.
Get Conversation
GET /conversations/{id}
Customers
List Customers
GET /customers
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
| string | Filter by email | |
| search | string | Search name/email |
| phone | string | Filter by phone |
| order_by | string | Sort field (e.g., created_at) |
| order_dir | string | Sort direction (asc or desc) |
| limit | integer | Items per page (max 100) |
| cursor | string | Cursor for pagination (ISO timestamp) |
Get Customer
GET /customers/{id}
Response:
{
"data": {
"id": "cust_456",
"email": "user@example.com",
"name": "John Doe",
"phone": "+1-555-0123",
"company": "Acme Inc",
"custom_fields": {},
"ticket_count": 5,
"created_at": "2025-01-01T00:00:00Z"
}
}
Create Customer
POST /customers
Body:
{
"email": "user@example.com",
"name": "John Doe",
"phone": "+1-555-0123",
"company": "Acme Inc"
}
Update Customer
PATCH /customers/{id}
Delete Customer
DELETE /customers/{id}
Users (Agents)
List Users
GET /users
Get User
GET /users/{id}
Tags
List Tags
GET /tags
Create Tag
POST /tags
Body:
{
"name": "billing",
"color": "#ff0000"
}
Get Tag
GET /tags/{id}
Update Tag
PATCH /tags/{id}
Delete Tag
DELETE /tags/{id}
Knowledge Base Articles
List Articles
GET /articles
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
| collection_id | string | Filter by collection |
| status | string | draft, published |
| search | string | Search content |
Get Article
GET /articles/{id}
Create Article
POST /articles
Body:
{
"title": "How to reset password",
"body": "Article content in markdown...",
"collection_id": "col_123",
"status": "draft"
}
Update Article
PATCH /articles/{id}
Delete Article
DELETE /articles/{id}
Error Responses
Error Format
{
"error": {
"code": "NOT_FOUND",
"message": "Ticket not found",
"details": {}
}
}
Common Errors
| Code | Status | Description |
|---|---|---|
| UNAUTHORIZED | 401 | Invalid or missing API key |
| FORBIDDEN | 403 | Insufficient permissions |
| NOT_FOUND | 404 | Resource not found |
| BAD_REQUEST | 400 | Invalid request data |
| TOO_MANY_REQUESTS | 429 | Too many requests |
| INTERNAL_SERVER_ERROR | 500 | Internal error |
Pagination
Request
Use limit and cursor parameters:
GET /tickets?limit=50&cursor=2025-01-15T10:30:00Z
Response
Includes pagination metadata:
{
"data": [...],
"meta": {
"limit": 50,
"total": 150,
"next_cursor": "2025-01-15T10:30:00Z"
}
}
Filtering
Operators
Some endpoints support filters:
GET /tickets?status=open&priority=high&assignee_id=uuid
Multiple Values
Use comma-separated values for tags:
GET /tickets?tags=billing,priority
Sorting
Sort Parameter
GET /tickets?order_by=created_at&order_dir=asc
GET /tickets?order_by=created_at&order_dir=desc
Available Sort Fields
Varies by endpoint. Common fields:
- created_at
- updated_at
- priority