WorkestraDocs
ModulesSupport

Developer API

Public REST endpoints for creating tickets, looking up status, searching knowledge base articles, and submitting CSAT feedback.

The Workestra public API lets external systems create tickets, check status, search the knowledge base, and submit customer feedback — without needing an agent session. Use it to integrate forms, internal tools, or third-party services with your support workflow.

Base URL

https://app.workestra.com

All public endpoints live under /api/public/.

Authentication

The public API supports two auth modes:

ModeWhen to Use
API keyBackend-to-backend integrations (CRMs, sync jobs, internal tools)
Magic-link tokenCustomer-facing flows (portal links, CSAT surveys, widget submissions)

API Key

Send the key in the Authorization header:

Authorization: Bearer wks_live_a1b2c3d4...

Create keys at Support > Settings > API Keys. See API Keys for scope details.

Token is passed as a ?t= query parameter on the URL:

GET /api/public/tickets/tkt_abc123?t=eyJhbGciOiJIUzI1...

Workestra issues these tokens automatically when:

  • A customer submits a ticket through the widget or portal — the confirmation email contains a tracking link
  • A ticket is resolved — the CSAT survey link contains a token
  • An admin shares a ticket from the agent UI

Tokens are scoped to a single ticket and expire after 30 days.

Rate Limits

Per IP address (or per API key, whichever is stricter):

EndpointLimit
POST /api/public/tickets10 per hour
GET /api/public/tickets/[id]5 per minute
POST /api/public/tickets/[id]/feedback3 per minute
GET /api/public/kb/search5 per minute
POST /api/public/kb/click30 per minute

Hitting a limit returns 429 Too Many Requests with a Retry-After header.

Endpoints

Create a Ticket

POST /api/public/tickets
Content-Type: application/json
Authorization: Bearer wks_live_...

Body:

{
  "workspace_id": "wks_abc123",
  "title": "Login broken on Safari",
  "description": "Repro: open https://example.com in Safari 17, click Sign In...",
  "type": "bug_report",
  "channel": "api",
  "customer_email": "alex@example.com",
  "customer_name": "Alex Chen",
  "priority": "high",
  "cc_emails": ["manager@example.com"],
  "metadata": { "source": "intercom-form" }
}

Response:

{
  "id": "tkt_xyz789",
  "reference": "TKT-0042",
  "status": "open",
  "tracking_url": "https://app.workestra.com/portal/.../tickets/tkt_xyz789?t=..."
}
FieldRequiredNotes
workspace_idYesYour workspace ID (find in Settings > General)
titleYesUp to 200 chars
descriptionNoMarkdown supported
typeNosupport_ticket, customer_request, bug_report, feature_request
channelNoDefaults to api
customer_emailYesUsed for replies and tracking
customer_nameNoUsed in confirmation emails
priorityNolow, medium, high, urgent — defaults to medium
cc_emailsNoUp to 20 — see CC Users
metadataNoFree-form JSON, returned in webhook payloads

The response includes a tracking_url with an embedded magic-link token — share this with the customer so they can view and reply to the ticket.

Get a Ticket

GET /api/public/tickets/{ticket_id}
Authorization: Bearer wks_live_...

Or with a magic-link token:

GET /api/public/tickets/{ticket_id}?t={token}

Response:

{
  "id": "tkt_xyz789",
  "reference": "TKT-0042",
  "title": "Login broken on Safari",
  "status": "in_progress",
  "priority": "high",
  "created_at": "2026-05-10T14:23:00Z",
  "updated_at": "2026-05-12T09:15:00Z",
  "resolved_at": null,
  "comments": [
    {
      "id": "cmt_...",
      "author_name": "Sarah (Workestra)",
      "author_kind": "agent",
      "body": "Thanks for reporting — investigating now.",
      "created_at": "2026-05-10T14:30:00Z"
    }
  ]
}

Internal notes are never returned to magic-link calls. API-key calls with tickets.read see them.

Submit CSAT Feedback

POST /api/public/tickets/{ticket_id}/feedback?t={token}
Content-Type: application/json

Body:

{
  "score": 5,
  "comment": "Solved fast and clearly. Thanks!"
}
FieldRequiredNotes
scoreYesInteger 1–5
commentNoUp to 1000 chars

Each ticket accepts at most one feedback submission. The token is single-use and expires after the first call.

Search the Knowledge Base

GET /api/public/kb/search?workspace_id={id}&q={query}&limit={n}

Returns up to limit (default 5, max 10) published KB articles matching the query. Used by the embeddable widget for ticket deflection.

Response:

{
  "results": [
    {
      "id": "art_...",
      "title": "Resetting your password",
      "snippet": "...go to **Settings > Account** and click **Reset password**...",
      "url": "https://app.workestra.com/portal/.../kb/art_..."
    }
  ]
}

This endpoint is unauthenticated (CORS-permissive) so the widget can call it from any origin.

Track a KB Click

POST /api/public/kb/click
Content-Type: application/json

{
  "workspace_id": "wks_...",
  "article_id": "art_...",
  "query": "reset password"
}

Fire-and-forget telemetry. Returns 200 even on internal errors (the widget shouldn't break if telemetry fails).

Errors

Errors return JSON with a stable shape:

{
  "error": {
    "code": "validation_error",
    "message": "title is required",
    "field": "title"
  }
}
StatusCodeMeaning
400validation_errorRequest body failed validation
401unauthorizedMissing or invalid auth
403forbiddenAuth valid but lacks the required scope
404not_foundTicket or workspace doesn't exist
429rate_limitedToo many requests — see Retry-After header
500internal_errorUnexpected server error — safe to retry

Versioning

The public API is currently v1 (the only version). Breaking changes will be introduced at /api/public/v2/.../api/public/... calls will keep working for at least 12 months after a v2 ships.

Webhooks vs. API

Public APIWebhooks
DirectionYou call usWe call you
CadenceOn demandReal-time on event
Best forOne-off queries, mutationsEvent-driven sync
Use togetherYes — webhook fires, your handler queries the API for full state

Next Steps

  • API Keys — Create the credentials you'll authenticate with
  • Webhooks — Receive events instead of polling
  • Widget — Customer-facing alternative to a custom form