Support Developer API
Create and read support tickets, add replies, submit CSAT, and search the public knowledge base.
The Support public API serves customer-facing ticket and knowledge-base flows. It is separate from the general /api/v1 API.
https://workspace.leenops.com/api/publicUse the workspace.leenops.com hostname directly. The apex and www hostnames are marketing surfaces, and some HTTP clients remove Authorization when following a cross-host redirect.
Authentication modes
| Mode | Use |
|---|---|
| API key | Server-to-server ticket creation, listing, lookup, and replies |
| Capability token | Customer ticket tracking, replies, reopening, and CSAT |
| Unauthenticated | Ticket creation with workspace_id, KB search, and KB click telemetry |
API-key requests use Authorization: Bearer wks_.... Customer tokens are issued by Leenops and must be treated as secrets.
Endpoint summary
| Method | Path | Authentication |
|---|---|---|
POST | /api/public/tickets | Optional API key; otherwise public and rate-limited |
GET | /api/public/tickets | tickets.read key, or t capability token |
POST | /api/public/tickets/{external_ticket_id} | tickets.write key, or token in the body |
PATCH | /api/public/tickets/{external_ticket_id} | Token in the body; reopens a ticket |
POST | /api/public/tickets/{external_ticket_id}/feedback | One-time CSAT token in the body |
GET | /api/public/kb/search | Public |
POST | /api/public/kb/click | Public |
The identifier in the ticket subpath is the public external_ticket_id, such as TKT-a1b2c3.
Create a ticket
curl -X POST https://workspace.leenops.com/api/public/tickets \
-H "Authorization: Bearer $LEENOPS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Alex Chen",
"email": "alex@example.com",
"subject": "Login broken on Safari",
"description": "Steps to reproduce...",
"type": "bug_report"
}'With an API key, Leenops derives workspace_id from the key. Without a key, workspace_id is required in the JSON body.
| Field | Required | Validation |
|---|---|---|
workspace_id | Public call only | UUID |
name | Yes | 1-200 characters |
email | Yes | Valid email |
subject | Yes | 1-200 characters |
description | No | Up to 5,000 characters |
type | No | support_ticket, customer_request, bug_report, or feature_request |
attachments | No | Up to 3 validated upload descriptors, each at most 50 MB |
The route does not accept title, customer_email, priority, channel, cc_emails, or arbitrary metadata.
Read tickets
API-key list:
curl "https://workspace.leenops.com/api/public/tickets?limit=50&offset=0" \
-H "Authorization: Bearer $LEENOPS_API_KEY"Use ?id=<uuid-or-external-id> for one ticket. limit defaults to 50 and is capped at 100.
Customer tracking uses the root endpoint, not a GET /tickets/{id} route:
GET /api/public/tickets?t=<capability-token>&ticket=<uuid-or-external-id>Token reads return the token holder's ticket list, the selected ticket, and public comments. Internal comments are excluded.
Reply or reopen
Add a reply:
POST /api/public/tickets/TKT-a1b2c3
{
"token": "<capability-token>",
"content": "Here is the additional information.",
"attachments": []
}An API key with tickets.write may omit token. content is 1-5,000 characters and up to three attachments are accepted.
Reopen:
PATCH /api/public/tickets/TKT-a1b2c3
{
"token": "<capability-token>",
"action": "reopen"
}Submit CSAT
POST /api/public/tickets/TKT-a1b2c3/feedback
{
"score": 5,
"comment": "Solved quickly.",
"token": "<one-time-csat-token>"
}score is an integer from 1 to 5 and comment is limited to 2,000 characters. The CSAT token is one-time and is consumed transactionally.
Knowledge base
GET /api/public/kb/search?workspace_id=<uuid>&q=reset%20password&limit=5limit defaults to 5 and is capped at 10. The route is public and CORS-enabled.
POST /api/public/kb/click
{
"workspace_id": "00000000-0000-0000-0000-000000000000",
"article_id": "00000000-0000-0000-0000-000000000000",
"query": "reset password"
}Click tracking accepts a query up to 200 characters and intentionally returns success even if telemetry storage fails.
Public-route rate limits
| Operation | Limit |
|---|---|
| Anonymous ticket creation | 10 per IP per hour |
| Token ticket lookup | 20 per IP per minute |
| Token ticket reply | 20 per IP per hour |
| CSAT submission | 20 per IP per hour |
| KB search | 5 per IP per minute |
| KB click | 30 per IP per minute |
Authenticated ticket creation, reads, and replies skip these anonymous IP limiters. See Rate Limits for the separate /api/v1 and MCP policies.
Errors
Support public routes return a top-level error string, sometimes with details; they do not use the general /api/v1 response envelope. Expect 400, 401, 403, 404, 429, and 500 depending on validation and authorization.

