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/public

Use 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

ModeUse
API keyServer-to-server ticket creation, listing, lookup, and replies
Capability tokenCustomer ticket tracking, replies, reopening, and CSAT
UnauthenticatedTicket 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

MethodPathAuthentication
POST/api/public/ticketsOptional API key; otherwise public and rate-limited
GET/api/public/ticketstickets.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}/feedbackOne-time CSAT token in the body
GET/api/public/kb/searchPublic
POST/api/public/kb/clickPublic

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.

FieldRequiredValidation
workspace_idPublic call onlyUUID
nameYes1-200 characters
emailYesValid email
subjectYes1-200 characters
descriptionNoUp to 5,000 characters
typeNosupport_ticket, customer_request, bug_report, or feature_request
attachmentsNoUp 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=5

limit 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

OperationLimit
Anonymous ticket creation10 per IP per hour
Token ticket lookup20 per IP per minute
Token ticket reply20 per IP per hour
CSAT submission20 per IP per hour
KB search5 per IP per minute
KB click30 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.