API Reference
Complete reference for the Kemon API endpoints and data models.
The Kemon API provides programmatic access to your workspace data. All endpoints are prefixed with /api/v1.
Authentication
API Key Required
Include your API key in the Authorization header for all requests.
curl -H "Authorization: Bearer your-api-key" \
https://api.kemon.io/api/v1/tickets
Base URL
https://api.kemon.io/api/v1
Tickets
List Tickets
/api/v1/ticketsReturns a paginated list of tickets in the current workspace.
Query Parameters
Prop
Type
Response
{
"data": [
{
"id": "01HQ3K5P7Y2XJMVR8N4W6TCA9B",
"identifier": "KEM-42",
"title": "Fix login redirect on mobile Safari",
"description": "Users on iOS Safari are not redirected after OAuth login.",
"status": "in_progress",
"priority": "high",
"assignee": {
"id": "01HQ3K5P7Y2XJMVR8N4W6TCA9C",
"name": "Jane Smith"
},
"labels": [{ "id": "01HQ3K5P7Y2XJMVR8N4W6TCA9D", "name": "bug" }],
"project_id": "01HQ3K5P7Y2XJMVR8N4W6TCA9E",
"created_at": "2025-11-15T10:30:00Z",
"updated_at": "2025-11-16T14:22:00Z"
}
],
"pagination": {
"page": 1,
"limit": 25,
"total": 134,
"total_pages": 6
}
}
Get Ticket
/api/v1/tickets/:idReturns a single ticket by ID, including comments.
Response
{
"data": {
"id": "01HQ3K5P7Y2XJMVR8N4W6TCA9B",
"identifier": "KEM-42",
"title": "Fix login redirect on mobile Safari",
"description": "Users on iOS Safari are not redirected after OAuth login.",
"status": "in_progress",
"priority": "high",
"assignee": {
"id": "01HQ3K5P7Y2XJMVR8N4W6TCA9C",
"name": "Jane Smith"
},
"labels": [{ "id": "01HQ3K5P7Y2XJMVR8N4W6TCA9D", "name": "bug" }],
"project_id": "01HQ3K5P7Y2XJMVR8N4W6TCA9E",
"comments": [
{
"id": "01HQ3K5P7Y2XJMVR8N4W6TCA9F",
"body": "Reproduced on iOS 17.4. Investigating the callback URL.",
"author": { "id": "01HQ3K5P7Y2XJMVR8N4W6TCA9C", "name": "Jane Smith" },
"created_at": "2025-11-15T11:00:00Z"
}
],
"created_at": "2025-11-15T10:30:00Z",
"updated_at": "2025-11-16T14:22:00Z"
}
}
Create Ticket
/api/v1/ticketsCreates a new ticket.
Request Body
Prop
Type
{
"title": "Add dark mode to settings page",
"description": "Users should be able to toggle dark mode from the settings panel.",
"status": "open",
"priority": "medium",
"assignee_id": "01HQ3K5P7Y2XJMVR8N4W6TCA9C",
"label_ids": ["01HQ3K5P7Y2XJMVR8N4W6TCA9D"],
"project_id": "01HQ3K5P7Y2XJMVR8N4W6TCA9E"
}{
"data": {
"id": "01HQ3K5P7Y2XJMVR8N4W6TCA9G",
"identifier": "KEM-135",
"title": "Add dark mode to settings page",
"description": "Users should be able to toggle dark mode from the settings panel.",
"status": "open",
"priority": "medium",
"assignee": {
"id": "01HQ3K5P7Y2XJMVR8N4W6TCA9C",
"name": "Jane Smith"
},
"labels": [{ "id": "01HQ3K5P7Y2XJMVR8N4W6TCA9D", "name": "bug" }],
"project_id": "01HQ3K5P7Y2XJMVR8N4W6TCA9E",
"created_at": "2025-11-17T09:00:00Z",
"updated_at": "2025-11-17T09:00:00Z"
}
}Update Ticket
/api/v1/tickets/:idUpdates an existing ticket. Only include fields you want to change.
{
"status": "done",
"priority": "low"
}{
"data": {
"id": "01HQ3K5P7Y2XJMVR8N4W6TCA9B",
"identifier": "KEM-42",
"title": "Fix login redirect on mobile Safari",
"status": "done",
"priority": "low",
"updated_at": "2025-11-18T16:45:00Z"
}
}Delete Ticket
/api/v1/tickets/:idDestructive Action
Permanently deletes a ticket. This action cannot be undone.
Returns 204 No Content with no response body.
Projects
List Projects
/api/v1/projectsReturns all projects in the workspace.
Query Parameters
Prop
Type
Response
{
"data": [
{
"id": "01HQ3K5P7Y2XJMVR8N4W6TCA9E",
"name": "Mobile App v2",
"description": "Complete redesign of the mobile application.",
"status": "active",
"lead": {
"id": "01HQ3K5P7Y2XJMVR8N4W6TCA9C",
"name": "Jane Smith"
},
"ticket_count": 42,
"created_at": "2025-10-01T08:00:00Z",
"updated_at": "2025-11-16T12:00:00Z"
}
],
"pagination": {
"page": 1,
"limit": 25,
"total": 8,
"total_pages": 1
}
}
Create Project
/api/v1/projectsCreates a new project.
Request Body
Prop
Type
{
"name": "API v2 Migration",
"description": "Migrate all endpoints from v1 to v2 schema.",
"status": "active",
"lead_id": "01HQ3K5P7Y2XJMVR8N4W6TCA9C"
}{
"data": {
"id": "01HQ3K5P7Y2XJMVR8N4W6TCA9H",
"name": "API v2 Migration",
"description": "Migrate all endpoints from v1 to v2 schema.",
"status": "active",
"lead": {
"id": "01HQ3K5P7Y2XJMVR8N4W6TCA9C",
"name": "Jane Smith"
},
"ticket_count": 0,
"created_at": "2025-11-17T09:30:00Z",
"updated_at": "2025-11-17T09:30:00Z"
}
}Rate Limiting
API requests are rate-limited per API key:
| Plan | Requests per minute |
|---|---|
| Free | 60 |
| Pro | 300 |
| Enterprise | 1000 |
Rate Limit Exceeded
When rate-limited, the API returns 429 Too Many Requests with a Retry-After header indicating
when you can retry.
Error Codes
Standard HTTP status codes are used. Error responses follow a consistent format:
{
"error": {
"code": "NOT_FOUND",
"message": "The requested ticket could not be found.",
"status": 404
}
}
| Status | Code | Description |
|---|---|---|
400 | BAD_REQUEST | Invalid request body or parameters |
401 | UNAUTHORIZED | Missing or invalid API key |
403 | FORBIDDEN | Insufficient permissions |
404 | NOT_FOUND | Resource not found |
409 | CONFLICT | Resource already exists |
422 | VALIDATION_ERROR | Request body failed validation |
429 | RATE_LIMITED | Too many requests |
500 | INTERNAL_ERROR | Server error — contact support |