Settings API

This article and the rest of the API documentation in this section are written for a technical audience — integrators and developers connecting external systems to Tickiti. Familiarity with HTTP, REST, JSON and bearer-token authentication is assumed.

The Settings API exposes the personal/shared Settings screens — perspectives, watchlists, hashtags and stock responses — over the bearer-token API. Every endpoint runs as the token’s owner and is gated by the settings ability plus the owner’s staff role, so a call can do exactly what that user could do in the interface (a non-admin still can’t edit a shared perspective, for example).

Abilities and conventions

  1. settings:read — read endpoints.
  2. settings:write — create / update / delete endpoints. Write implies read, so a write token also satisfies the read endpoints.

All endpoints are POST and JSON, except the stock-response image upload, which is multipart. Request and response shapes match the corresponding Settings screen; the sections below cover the key fields. Validation, plan caps and ownership rules are the same as the UI because the API reuses that code. A refused request returns HTTP 422 (or 403 where the owner’s role does not allow the action) with a message saying why; the watchlist endpoints report a refusal in a my_error field of the reply.

Endpoints

Method & pathAbilityPurpose
POST /api/v1/settings/perspectivessettings:readList perspectives (scope: mine or all)
POST /api/v1/settings/perspectives/showsettings:readFetch one perspective with its conditions and sort orders (perspective_id or name)
POST /api/v1/settings/perspectives/createsettings:writeCreate a perspective (name, shared, conditions, orders)
POST /api/v1/settings/perspectives/updatesettings:writeUpdate a perspective by perspective_id; only the fields sent change
POST /api/v1/settings/perspectives/deletesettings:writeDelete a perspective by perspective_id
POST /api/v1/settings/watchlistssettings:readList visible watchlists (+ colour pickers)
POST /api/v1/settings/watchlists/createsettings:writeCreate a watchlist (name, icon, shared)
POST /api/v1/settings/watchlists/updatesettings:writeUpdate a watchlist by watchlist_id
POST /api/v1/settings/watchlists/deletesettings:writeDelete a watchlist by watchlist_id
POST /api/v1/settings/watchlists/add-ticketssettings:writeAdd ticket_ids to a watchlist
POST /api/v1/settings/watchlists/remove-ticketssettings:writeRemove ticket_ids from a watchlist
POST /api/v1/settings/watchlists/reordersettings:writeReorder a watchlist’s tickets
POST /api/v1/settings/hashtagssettings:readList/search hashtags (optional q)
POST /api/v1/settings/hashtags/deletesettings:writeDelete a tag everywhere (tag; admin only)
POST /api/v1/settings/stock-responsessettings:readList stock responses (optional search, include_content)
POST /api/v1/settings/stock-responses/showsettings:readFetch one stock response by template_id
POST /api/v1/settings/stock-responses/createsettings:writeCreate a stock response
POST /api/v1/settings/stock-responses/updatesettings:writeUpdate a stock response (template object); only the fields sent change
POST /api/v1/settings/stock-responses/image-uploadsettings:writeUpload an image for a stock response (multipart template_id + file)
POST /api/v1/settings/stock-responses/deletesettings:writeDelete a stock response by template_id

Perspectives

Listing. perspectives takes an optional scope:

  1. mine (the default) — the perspectives on the caller’s own index page, in the caller’s order, each with its conditions, sort orders, ticket count and watchlist details. An account that has never arranged its index page gets an empty list here.
  2. all — every perspective the caller may see, built-ins included, each with its conditions and sort orders, ordered by name. That is the shared perspectives plus the caller’s own; an admin sees every user’s.

Reading one. perspectives/show takes perspective_id, or name — a name is looked up among the shared perspectives and the caller’s own, the caller’s own winning a tie. The reply is {"perspective": {...}} with its conditions (field, operator, value), orders (ordinal, field, ascending), owner and impersonated user. An unknown perspective is a 404; another user’s personal perspective is a 403 for a non-admin.

Creating. perspectives/create takes name (required, up to 255 characters) and shared (required boolean), plus optional description, display_mode (card or list), show_in_crm, impersonate_user_id, user_id (an admin creating a personal perspective for another user), conditions (an array of {field, operator, value}, where operator is =, != or like) and orders (an array of {field, ascending}, highest priority first). A perspective’s name is unique for its owner, and the plan’s custom and shared perspective limits apply. The reply carries the new perspective_id. Read an existing perspective with show to see the condition and sort field names in use.

Updating. perspectives/update takes perspective_id and changes only the fields sent; everything left out keeps its value. conditions and orders are each replaced as a whole when sent and kept when left out — send an empty array to clear one. For example, to change only the description:

{
  "perspective_id": 42,
  "description": "Open Sales tickets, oldest first"
}

Built-in perspectives cannot be edited or deleted, and the perspective a watchlist creates for itself is managed through the watchlist.

Watchlists and hashtags

  1. watchlists returns the watchlists the caller can see (shared ones plus their own; an admin sees all), each with its ticket count and whether it is in the caller’s perspectives, together with the colours still available for new shared and private watchlists.
  2. watchlists/create takes name, icon and shared, with optional description, display_mode, show_in_my_perspectives and ticket_ids to start it with. watchlists/update takes watchlist_id with name and icon on every call. A watchlist’s owner and shared status stay fixed while it holds tickets.
  3. watchlists/delete leaves a watchlist that still holds tickets in place and returns my_error with its ticket_count; send force: true to delete it anyway. The tickets themselves are untouched.
  4. hashtags returns up to 500 tags in use on live tickets, each with a use_count, filtered by q when given; truncated is true when there are more.

Stock responses

Listing. stock-responses returns each stock response’s id, title, category, subcategory, keywords, subject, use_count and whether it is one of the caller’s favourites. search filters by title, keywords, subject or body; include_content: true adds each content (inline images embedded as data: URIs), is_enabled and ai_relevance.

Reading one. stock-responses/show takes template_id and returns the full record, content included.

Creating. stock-responses/create takes:

  1. identifier — the topic title shown in the composer’s picker. Unique among stock responses.
  2. category and optional subcategory — the grouping. Give a category when creating one: an update to a stock response is refused while it has none.
  3. subject, keywords (comma- or newline-separated) and content (Quill HTML). Pasted data: images in content are stored as the stock response’s own images.
  4. is_enabled — whether it appears in the composer; defaults to true. Send false to prepare one before staff can use it.
  5. notes — internal guidance for staff.
  6. ai_relevance — how the AI assistant may use it: as_is, compose, reference (the default) or exclude. Set only when the token’s owner is an admin.

Updating. stock-responses/update takes a template object holding the stock response’s id and only the fields to change; every field left out keeps its value. Alongside the create fields, an admin owner may set ai_hands_over.

{
  "template": {
    "id": 457,
    "content": "<p>Your replacement unit ships within two working days.</p>"
  }
}

Images. To illustrate a stock response, upload the image to stock-responses/image-upload as multipart form data with template_id and file. The reply gives the image’s cid, sha256, mime_type and a ready-made img tag (<img src="cid:...">); place that tag in the content with an update. Uploading the same image again returns the same cid.

curl -X POST https://support.sole-trader.example/api/v1/settings/stock-responses/image-upload \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -F template_id=457 \
  -F [email protected]

Limits and refusals. Text fields are limited to 255 characters, content and notes excepted. A refusal — a field over the limit, a duplicate topic, a missing category, a file that is not an image — is a 422 with a message naming the problem, for example Subject is 300 characters; the limit is 255. A call without its id is a 422 naming the parameter; an id that is not a stock response is a 404 or 403.

Notes

  1. The stock-response endpoints act on stock responses only. Templates and FAQs are managed through the Templates API.
  2. Hashtag delete requires the owner to be an admin (enforced in-app), even with a settings:write token.
  3. Shared perspectives/watchlists can only be created or edited by an admin owner; everyone else is limited to their own.