A tenant-scoped REST API to create and manage tickets from your own systems. JSON over HTTPS. a product from Smart Products company.
All requests use a secret API key as a Bearer token. Generate one in
your workspace under Settings → API keys
(admin only). The key is shown once — store it securely. Keys look like sptk_… and are scoped to the user who created them, so the API enforces that user's role permissions.
Authorization: Bearer sptk_xxxxxxxxxxxxxxxxxxxxxxxx
Each workspace has its own base URL on its subdomain:
https://acme.sp-tickets.stuff-testing.lol/api
Verify your key and see its permissions:
curl -s https://acme.sp-tickets.stuff-testing.lol/api/me \
-H "Authorization: Bearer $SP_TOKEN"
Errors return a non-2xx status and { "error": "code", ... }. Common codes:
| Status | Meaning |
|---|---|
401 | Missing/invalid token (unauthorized, invalid_token) |
403 | Token lacks a permission (forbidden, missing_permission) or workspace is read-only |
404 | Resource not found (also returned for another tenant's IDs — strict isolation) |
409 | Invalid ticket status transition |
400 | Validation error (e.g. subject_required) |
A machine-readable spec is at https://acme.sp-tickets.stuff-testing.lol/api/openapi.json.
/tickets — list (query: status, limit≤200, offset). Needs ticket.view.curl -s "https://acme.sp-tickets.stuff-testing.lol/api/tickets?status=open&limit=20" \
-H "Authorization: Bearer $SP_TOKEN"
/tickets — create. Needs ticket.create.curl -s -X POST https://acme.sp-tickets.stuff-testing.lol/api/tickets \
-H "Authorization: Bearer $SP_TOKEN" -H "Content-Type: application/json" \
-d '{"subject":"Printer is down","description":"3rd floor","priority_id":"<optional>"}'
Response: 201 with { "ticket": { "ref": "T-0001", ... } }. Omit priority_id to use the tenant default.
/tickets/{id} — retrieve. Needs ticket.view./tickets/{id} — update. Each field needs its permission: fields ticket.edit, status ticket.transition, assignee_id ticket.assign.curl -s -X PATCH https://acme.sp-tickets.stuff-testing.lol/api/tickets/tkt_abc123 \
-H "Authorization: Bearer $SP_TOKEN" -H "Content-Type: application/json" \
-d '{"status":"open","assignee_id":"usr_xyz"}'
Changing category_id/priority_id recalculates SLA due dates. Lifecycle: New → Open → Pending → Resolved → Closed (and reopen).
/tickets/{id}/comments — internal notes are included only with comment.internal./tickets/{id}/comments — needs comment.create; internal:true needs comment.internal.curl -s -X POST https://acme.sp-tickets.stuff-testing.lol/api/tickets/tkt_abc123/comments \
-H "Authorization: Bearer $SP_TOKEN" -H "Content-Type: application/json" \
-d '{"body":"Working on it","internal":false}'
/categories/prioritiesUse the returned IDs when creating or updating tickets.
Point your mail or payment provider at these host-level endpoints (shared-secret, JSON). They are not tenant-subdomain scoped — pass the tenant subdomain in the body.
https://sp-tickets.stuff-testing.lol/hooks/inbound-email — email → ticket (or comment + reopen if the subject has [T-####]).curl -s -X POST https://sp-tickets.stuff-testing.lol/hooks/inbound-email \
-H "Content-Type: application/json" \
-d '{"secret":"$INBOUND_SECRET","tenant":"acme","from":"user@acme.com","subject":"Help","text":"..."}'
https://sp-tickets.stuff-testing.lol/hooks/support-inbound — email → provider support request.https://sp-tickets.stuff-testing.lol/hooks/billing — payment events: invoice.paid, payment.failed, subscription.cancelled, subscription.reinstated.© 2026 Smart Products company.