Skip to content

REST API

Support API

REST endpoints for the Support area of Lessly.

The Support area publishes 44 REST endpoints. Paths are relative to https://api.lessly.com; see Authentication for the required header.

GET/support/agents

List this product support agents by display name. Deactivated agents are hidden unless asked for: they keep every message they wrote but cannot take new threads. Through the public edge the profiles come back without lesslyUserId — the binding never leaves the authenticated plane

MCP tool: support_agent_list

Parameters

NameInTypeRequiredDescription
includeInactivequerybooleanAlso return deactivated agents (default false)

Response

FieldTypeAlwaysDescription
agentsarrayThe product support agents, by display name
POST/support/agents

Create a support agent profile for this product. Binding a Lessly identity is optional and the value is stored verbatim — nothing resolves it or checks that the user exists. An unbound profile is a bot or the client's own backend, and it replies exactly like a human agent does

MCP tool: support_agent_create

Parameters

NameInTypeRequiredDescription
displayNamebodystringName the end user sees next to this agent replies
titlebodystringJob title shown under the name, e.g. "Support engineer"
avatarUrlbodystringAbsolute URL of the agent avatar image
lesslyUserIdbodystringLessly identity to bind this profile to, stored verbatim as an opaque string. It is never resolved, validated against the platform or enriched. Omit it for a bot or a backend profile. At most one agent per product may claim a given Lessly user

Response

FieldTypeAlwaysDescription
idstringAgent id
titlestringJob title shown under the name, or null if unset
isActivebooleanA deactivated agent keeps its history but can no longer be put on a thread
avatarUrlstringAvatar image URL, or null if unset
createdAtstringISO-8601 creation timestamp
updatedAtstringISO-8601 last-modification timestamp
displayNamestringName shown next to the agent replies
lesslyUserIdstringBound Lessly identity, stored verbatim and resolved by nobody. Null for an unbound profile — a bot or the client's own backend, which replies just like anyone else
GET/support/agents/:id

Get one support agent by id, deactivated ones included. An agent belonging to another product is reported as not found. Through the public edge the profile comes back without lesslyUserId — the binding never leaves the authenticated plane

MCP tool: support_agent_get

Parameters

NameInTypeRequiredDescription
idpathstringAgent id

Response

FieldTypeAlwaysDescription
idstringAgent id
titlestringJob title shown under the name, or null if unset
isActivebooleanA deactivated agent keeps its history but can no longer be put on a thread
avatarUrlstringAvatar image URL, or null if unset
createdAtstringISO-8601 creation timestamp
updatedAtstringISO-8601 last-modification timestamp
displayNamestringName shown next to the agent replies
lesslyUserIdstringBound Lessly identity, stored verbatim and resolved by nobody. Null for an unbound profile — a bot or the client's own backend, which replies just like anyone else
PATCH/support/agents/:id

Edit an agent profile. Pass null to clear the title, the avatar or the Lessly binding; omit a field to leave it alone. Setting isActive to false deactivates the agent: it keeps every message it wrote and every thread it already sits on, but cannot be assigned to another one

MCP tool: support_agent_update

Parameters

NameInTypeRequiredDescription
idpathstringAgent id
displayNamebodystringName the end user sees next to this agent replies
titlebodystringNew job title, or null to clear it
avatarUrlbodystringNew avatar URL, or null to clear it
lesslyUserIdbodystringLessly identity to bind, or null to unbind. Stored verbatim, resolved by nobody
isActivebodybooleanDeactivate or reactivate. A deactivated agent keeps every message it wrote and every thread it already sits on, but cannot be assigned to another one

Response

FieldTypeAlwaysDescription
idstringAgent id
titlestringJob title shown under the name, or null if unset
isActivebooleanA deactivated agent keeps its history but can no longer be put on a thread
avatarUrlstringAvatar image URL, or null if unset
createdAtstringISO-8601 creation timestamp
updatedAtstringISO-8601 last-modification timestamp
displayNamestringName shown next to the agent replies
lesslyUserIdstringBound Lessly identity, stored verbatim and resolved by nobody. Null for an unbound profile — a bot or the client's own backend, which replies just like anyone else
POST/support/attachments

Reserve a file on a support thread and get a short-lived signed URL to upload it to. The bytes never pass through this API: PUT them to the returned uploadUrl with the same Content-Type, then call support_attachment_finalize. Until finalized the attachment is pending — it cannot be attached to a message and is invisible in message output. A thread belonging to another product is reported as not found

MCP tool: support_attachment_create

Parameters

NameInTypeRequiredDescription
threadIdbodystringThread the file belongs to. An attachment is created against a thread first and claimed by one of its messages later, when that message is posted
fileNamebodystringDisplay name of the file, e.g. "invoice.pdf". Only the base name is used for the storage key; any directory part is discarded
contentTypebodystringMIME type of the file. The upload URL is signed for exactly this type, so the PUT must send the same Content-Type header or storage rejects it
sizeBytesbodyintegerSize of the file in bytes, at most 26214400. Declared up front so an oversized upload is refused before a URL is issued; finalize checks the real size again

Response

FieldTypeAlwaysDescription
idstringAttachment id
statusstringpending: the row exists and an upload URL was issued, but no bytes have been confirmed. uploaded: finalize saw the object in storage. Only uploaded attachments can be attached to a message or downloaded
fileNamestringDisplay name of the file
threadIdstringThread this attachment belongs to
createdAtstringISO-8601 creation timestamp
messageIdstringThe message that carries this attachment, or null while nothing claims it yet
sizeBytesintegerSize in bytes: what the caller declared while the attachment is pending, what storage reported once it is uploaded
uploadUrlstringShort-lived signed URL. PUT the file bytes here with the same Content-Type, then call support_attachment_finalize. The URL is a bearer credential for this one object
uploadedAtstringISO-8601 timestamp of the confirmed upload, or null while pending
contentTypestringMIME type declared when the attachment was created
uploadExpiresAtstringISO-8601 moment the upload URL stops working
POST/support/attachments/finalize

Confirm that an upload landed. Storage is asked whether the object exists and how large it is; if it is not there the call is refused and the attachment stays pending. On success the attachment becomes uploaded — it can now be named in support_message_create and carries a download URL. Calling it again on an uploaded attachment is safe and simply returns a fresh download URL

MCP tool: support_attachment_finalize

Parameters

NameInTypeRequiredDescription
attachmentIdbodystringThe attachment whose upload should be confirmed, as returned by the create call

Response

FieldTypeAlwaysDescription
idstringAttachment id
statusstringpending: the row exists and an upload URL was issued, but no bytes have been confirmed. uploaded: finalize saw the object in storage. Only uploaded attachments can be attached to a message or downloaded
fileNamestringDisplay name of the file
threadIdstringThread this attachment belongs to
createdAtstringISO-8601 creation timestamp
messageIdstringThe message that carries this attachment, or null while nothing claims it yet
sizeBytesintegerSize in bytes: what the caller declared while the attachment is pending, what storage reported once it is uploaded
uploadedAtstringISO-8601 timestamp of the confirmed upload, or null while pending
contentTypestringMIME type declared when the attachment was created
downloadUrlstringShort-lived signed URL to read the uploaded file
GET/support/labels

List this product label dictionary by name. A product that has invented no tags yet gets an empty list — unlike statuses, there is nothing to seed

MCP tool: support_label_list

Parameters

No parameters.

Response

FieldTypeAlwaysDescription
labelsarrayThe product label dictionary, by name
POST/support/labels

Add a label to this product label dictionary. A label is a free-form tag: nothing automates off it and a thread may carry any number of them. Names are unique per product

MCP tool: support_label_create

Parameters

NameInTypeRequiredDescription
namebodystringLabel name as the customer wants to see it. Unique within the product
colorbodystringOptional display colour as a six-digit hex string, e.g. #2563eb

Response

FieldTypeAlwaysDescription
idstringLabel id
namestringLabel name, unique within the product
colorstringDisplay colour as a hex string, or null if uncoloured
createdAtstringISO-8601 creation timestamp
GET/support/messages

List messages oldest first — the conversation reads forward. Name a threadId to read one thread, or omit it to read every thread of this product, which is how a client catches up on what it missed: pass since with the timestamp of the last message it has, then follow nextCursor until it comes back null. Paging is stable across messages that share a timestamp, so a walk neither skips nor repeats one. Filter by direction and by visibility; omit visibility to get public messages and internal notes together. A thread belonging to another product is reported as not found

MCP tool: support_message_list

Parameters

NameInTypeRequiredDescription
threadIdquerystringThread whose messages to list. Omit to list the messages of every thread of this product — the catch-up read
directionquerystringOnly messages in this direction
visibilityquerystringOnly messages with this visibility. Omit to get both public and internal
sincequerystringISO-8601 timestamp. Only messages created strictly after it — pass the createdAt of the last message you already have
cursorquerystringOpaque position from a previous nextCursor. Resumes exactly where that page ended, with no gap and no repeat even when messages share a timestamp. Never construct one, and do not combine it with offset
limitqueryintegerPage size, 1..100 (default 50)
offsetqueryintegerNumber of messages to skip. The older pagination, kept for callers that already use it; prefer cursor, which cannot drift as messages arrive

Response

FieldTypeAlwaysDescription
limitintegerPage size that was applied
offsetintegerOffset that was applied
messagesarrayThe requested page of messages, oldest first — the conversation reads forward
nextCursorstringPosition to resume from: pass it back as cursor for the next page. Null when this page is the last one
POST/support/messages

Post a message into a support thread. A message has exactly one author: either an opaque external identifier from the client's own user base, or a support agent — never both and never neither. Direction, authorship and visibility are independent: an internal note may be inbound or outbound. Posting a message moves the parent thread's last reply timestamp. A message may carry files: create and finalize them first, then name them in attachmentIds. Through the public edge an agent author is accepted only if that agent carries no Lessly binding — a bot or the calling backend; an agent bound to a Lessly identity may author only from a signed-in session

MCP tool: support_message_create

Parameters

NameInTypeRequiredDescription
threadIdbodystringId of the thread this message belongs to
bodybodystringThe message text, stored verbatim
directionbodystringinbound: written by the external end user. outbound: written by support, going out to them
authorExternalIdbodystringOpaque identifier of the external end user in the client's own user base, stored verbatim. Set this exactly when the message comes from outside; leave authorAgentId empty
authorAgentIdbodystringThe support agent of this product who wrote the message. Set this exactly when the message comes from inside the support contour; leave authorExternalId empty. An agent of another product is reported as not found
visibilitybodystringDefaults to public when omitted. Internal notes are never shown to the end user
attachmentIdsbodyarrayFiles this message carries, created with support_attachment_create and confirmed with support_attachment_finalize beforehand. Each must be an uploaded attachment of the same thread that no other message already carries; otherwise the whole message is refused. At most 10 per message

Response

FieldTypeAlwaysDescription
idstringMessage id
bodystringThe message text, byte-identical to what was stored
threadIdstringThread this message belongs to
createdAtstringISO-8601 creation timestamp
directionstringinbound: written by the external end user. outbound: written by support, going out to them
visibilitystringpublic: part of the conversation the external end user sees. internal: a note between agents that never leaves the support contour
attachmentsarrayFiles this message carries, each with a freshly signed download URL. Empty when there are none. Attachments whose upload was never confirmed are never listed here
authorAgentIdstringThe agent author, or null when the external end user wrote the message
authorExternalIdstringThe external author, or null when an agent wrote the message
GET/support/responses

List the responses of ONE survey, newest first — surveyId is required, because a page mixing two surveys would carry answers keyed by two different question sets. Filters: score range (scoreMin/scoreMax, inclusive — a response with no score matches neither bound), a creation window (from/to), completed, plus pagination

MCP tool: support_response_list

Parameters

NameInTypeRequiredDescription
surveyIdquerystringRequired: responses are always read one survey at a time
scoreMinqueryintegerOnly responses scored at or above this value (inclusive). A response with no score matches neither bound — not even at the bottom of the scale
scoreMaxqueryintegerOnly responses scored at or below this value (inclusive). A response with no score matches neither bound — not even at the bottom of the scale
fromquerystringOnly responses created at or after this ISO-8601 timestamp
toquerystringOnly responses created at or before this ISO-8601 timestamp
completedquerybooleantrue: only responses that reached the end. false: only partial ones
limitqueryintegerPage size, 1..100 (default 25)
offsetqueryintegerNumber of responses to skip

Response

FieldTypeAlwaysDescription
limitintegerPage size that was applied
offsetintegerOffset that was applied
responsesarrayThe requested page of responses, newest first
GET/support/responses/:id

Get one survey response by id, with its answers exactly as they were submitted. A response belonging to another product is reported as not found

MCP tool: support_response_get

Parameters

NameInTypeRequiredDescription
idpathstringResponse id

Response

FieldTypeAlwaysDescription
idstringResponse id
scoreintegerThe answer of the first nps or rating question, raw and never rescaled, or null when neither was answered. Null is not zero — 0 is a real score at the bottom of an NPS scale
answersobjectAnswers keyed by question id, exactly as stored
metadataobjectFree-form client-owned JSON
surveyIdstringThe survey that was answered
completedbooleanWhether the respondent reached the end
createdAtstringISO-8601 creation timestamp
updatedAtstringISO-8601 last-modification timestamp
authorExternalIdstringThe respondent, byte-identical to what was stored
escalatedThreadIdstringThe feedback thread this response was escalated into, or null while it has not been
POST/support/responses/:id/escalate

Turn a survey response into a feedback thread so a person can follow up. The thread opens on the product’s default open status, titled with the survey’s name, authored by the same external respondent, carrying the response metadata plus surveyResponseId, and rated with the response score when it fits 0..10. No message is written — the answers stay on the response, and neither the end user nor an agent typed anything. A response that was already escalated is refused with a conflict naming the thread it went to

MCP tool: support_response_escalate

Parameters

NameInTypeRequiredDescription
idpathstringResponse id

Response

FieldTypeAlwaysDescription
threadobjectThe feedback thread that was opened
responseobjectThe response, with escalatedThreadId now set
GET/support/rules

List this product’s delivery rules, newest first, optionally narrowed to one survey, to the live or switched-off ones, or to the rules that apply to a given page URL and device. This is the same answer a client’s runtime fetches through the public edge, where a URL is required and only live rules on published surveys are visible

MCP tool: support_rule_list

Parameters

NameInTypeRequiredDescription
surveyIdquerystringOnly rules delivering this survey
enabledquerybooleantrue: only live rules. false: only switched-off ones
urlquerystringOnly rules whose URL match applies to this page URL
devicequerystringThe device the page is rendered on. Without it only rules targeting any device match
limitqueryintegerPage size, 1..100 (default 25)
offsetqueryintegerNumber of rules to skip

Response

FieldTypeAlwaysDescription
limitintegerPage size that was applied
rulesarrayThe requested page of rules, newest first
offsetintegerOffset that was applied
POST/support/rules

Write a delivery rule: where a survey should be shown (a URL match), on which devices, when (immediately, after a delay, or on the client’s own event) and how often. Nothing here runs on this side — the rule is configuration a client’s own runtime reads back through the public edge and acts on. A rule reaches that edge only while its survey is published, so a rule may be written against a draft and simply waits

MCP tool: support_rule_create

Parameters

NameInTypeRequiredDescription
surveyIdbodystringThe survey this rule delivers. It must belong to this product
urlMatchbodyobjectWhich pages this rule applies to
triggerbodyobjectWhen to show the survey once the page matches
frequencybodyobjectHow often the same person may see this survey
devicebodystringWhich devices this rule applies to (default any)
enabledbodybooleanWhether the rule is live. A rule is created enabled unless this says otherwise
attributeConditionsbodyarrayConditions on the visitor’s attributes. Omit for a rule that applies to everyone

Response

FieldTypeAlwaysDescription
idstringRule id
devicestringWhich devices the rule applies to. any is the rule that does not care and is the default
enabledbooleanWhether the rule is live
triggerobject
surveyIdstringThe survey this rule delivers
urlMatchobjectWhich pages match
createdAtstringISO-8601 creation timestamp
frequencyobject
updatedAtstringISO-8601 last-modification timestamp
attributeConditionsarrayConditions on the visitor’s attributes, ALL of which must hold
DELETE/support/rules/:id

Delete a delivery rule for good. Unlike a survey, a rule is not archived — it has no responses behind it and nothing outlives it, so the row is removed and cannot be recovered. The survey it targeted is untouched. To stop delivery reversibly, set enabled to false instead

MCP tool: support_rule_delete

Parameters

NameInTypeRequiredDescription
idpathstringRule id

Response

FieldTypeAlwaysDescription
idstringId of the rule that was deleted
deletedbooleanAlways true — the rule is gone
GET/support/rules/:id

Get one delivery rule by id, with its whole configuration. A rule belonging to another product is reported as not found

MCP tool: support_rule_get

Parameters

NameInTypeRequiredDescription
idpathstringRule id

Response

FieldTypeAlwaysDescription
idstringRule id
devicestringWhich devices the rule applies to. any is the rule that does not care and is the default
enabledbooleanWhether the rule is live
triggerobject
surveyIdstringThe survey this rule delivers
urlMatchobjectWhich pages match
createdAtstringISO-8601 creation timestamp
frequencyobject
updatedAtstringISO-8601 last-modification timestamp
attributeConditionsarrayConditions on the visitor’s attributes, ALL of which must hold
PATCH/support/rules/:id

Edit a delivery rule: its URL match, device, trigger, frequency, conditions, or whether it is live at all. Every value replaces the old one whole rather than merging into it. The survey is not editable — a rule is the targeting OF one survey, and retargeting it silently would change what every matching page shows; delete it and write the one you meant. Switching a rule off is the quiet way to stop delivering without touching the survey

MCP tool: support_rule_update

Parameters

NameInTypeRequiredDescription
idpathstringRule id
urlMatchbodyobjectThe new URL match, replacing the old one
triggerbodyobjectThe new trigger, replacing the old one
frequencybodyobjectThe new frequency, replacing the old one
devicebodystringThe new device targeting
enabledbodybooleanTurn the rule on or off
attributeConditionsbodyarrayThe complete new condition set, replacing the old one. Pass [] to clear it

Response

FieldTypeAlwaysDescription
idstringRule id
devicestringWhich devices the rule applies to. any is the rule that does not care and is the default
enabledbooleanWhether the rule is live
triggerobject
surveyIdstringThe survey this rule delivers
urlMatchobjectWhich pages match
createdAtstringISO-8601 creation timestamp
frequencyobject
updatedAtstringISO-8601 last-modification timestamp
attributeConditionsarrayConditions on the visitor’s attributes, ALL of which must hold
GET/support/statuses

List this product status dictionary in display order. A product that never opened settings gets the four defaults seeded on the first call. Archived statuses are hidden unless asked for

MCP tool: support_status_list

Parameters

NameInTypeRequiredDescription
includeArchivedquerybooleanAlso return archived statuses (default false)

Response

FieldTypeAlwaysDescription
statusesarrayThe product status dictionary, in display order
POST/support/statuses

Add a status to this product status dictionary. The name is what people see; the category is what automation and reporting read, and it cannot change once threads sit on the status

MCP tool: support_status_create

Parameters

NameInTypeRequiredDescription
namebodystringStatus name as the customer wants to see it. Unique within the product
colorbodystringDisplay colour as a six-digit hex string, e.g. #2563eb
orderbodyintegerSort order within the status dictionary, lowest first
categorybodystringLifecycle bucket the status belongs to. Automation and reporting read the category, never the name — so it cannot be changed once threads sit on the status

Response

FieldTypeAlwaysDescription
idstringStatus id
namestringStatus name, unique within the product
colorstringDisplay colour as a hex string
orderintegerSort order within the status dictionary
archivedbooleanArchived statuses stay readable but are not offered as targets
categorystringLifecycle bucket the status belongs to
PATCH/support/statuses/:id

Rename, recolour or reorder a status. The category may only change while no thread references the status: changing it later would rewrite the history of every metric derived from it. A status belonging to another product is reported as not found

MCP tool: support_status_update

Parameters

NameInTypeRequiredDescription
idpathstringStatus id
namebodystringStatus name as the customer wants to see it. Unique within the product
colorbodystringDisplay colour as a six-digit hex string, e.g. #2563eb
orderbodyintegerSort order within the status dictionary, lowest first
categorybodystringNew lifecycle bucket. Refused while any thread references the status

Response

FieldTypeAlwaysDescription
idstringStatus id
namestringStatus name, unique within the product
colorstringDisplay colour as a hex string
orderintegerSort order within the status dictionary
archivedbooleanArchived statuses stay readable but are not offered as targets
categorystringLifecycle bucket the status belongs to
POST/support/statuses/:id/archive

Retire a status. There is no way to delete one: every thread on it moves to the target status in the same transaction, so no thread is ever left on an archived status. The target must be a different, live status of this product

MCP tool: support_status_archive

Parameters

NameInTypeRequiredDescription
idpathstringStatus id
targetStatusIdbodystringLive status every thread on the archived status moves to, in the same transaction

Response

FieldTypeAlwaysDescription
idstringStatus id
namestringStatus name, unique within the product
colorstringDisplay colour as a hex string
orderintegerSort order within the status dictionary
archivedbooleanArchived statuses stay readable but are not offered as targets
categorystringLifecycle bucket the status belongs to
GET/support/surveys

List this product’s surveys, newest first, optionally narrowed to one lifecycle state (draft, published or archived), with pagination

MCP tool: support_survey_list

Parameters

NameInTypeRequiredDescription
statusquerystringOnly surveys in this lifecycle state
limitqueryintegerPage size, 1..100 (default 25)
offsetqueryintegerNumber of surveys to skip

Response

FieldTypeAlwaysDescription
limitintegerPage size that was applied
offsetintegerOffset that was applied
surveysarrayThe requested page of surveys, newest first
POST/support/surveys

Open a new survey. It starts as a draft — editable and not yet answerable — whatever questions travel with it. There is no way to create one already published: publishing runs the structure validator, and a create that skipped it would be a second way in

MCP tool: support_survey_create

Parameters

NameInTypeRequiredDescription
namebodystringWhat this survey is called. It becomes the title of an escalated feedback thread
questionsbodyarrayThe initial question set. Omit it to open an empty draft and fill it in later

Response

FieldTypeAlwaysDescription
idstringSurvey id
namestringWhat this survey is called
statusstringdraft: editable, not answerable. published: answerable, frozen. archived: terminal, neither editable nor answerable, and there is no way back
createdAtstringISO-8601 creation timestamp
questionsarrayThe ordered question set, exactly as stored
updatedAtstringISO-8601 last-modification timestamp
GET/support/surveys/:id

Get one survey by id, with its whole question set. A survey belonging to another product is reported as not found. Through the public edge only a PUBLISHED survey is readable — a draft or an archived one is reported as not found there

MCP tool: support_survey_get

Parameters

NameInTypeRequiredDescription
idpathstringSurvey id

Response

FieldTypeAlwaysDescription
idstringSurvey id
namestringWhat this survey is called
statusstringdraft: editable, not answerable. published: answerable, frozen. archived: terminal, neither editable nor answerable, and there is no way back
createdAtstringISO-8601 creation timestamp
questionsarrayThe ordered question set, exactly as stored
updatedAtstringISO-8601 last-modification timestamp
PATCH/support/surveys/:id

Edit a survey’s name or question set. Only a draft is editable — publishing freezes the structure, because answers are keyed by question id and rewriting the questions under them would change what every collected response was answering. To edit a live survey, unpublish it first. questions replaces the whole set; pass an empty array to clear it

MCP tool: support_survey_update

Parameters

NameInTypeRequiredDescription
idpathstringSurvey id
namebodystringNew name
questionsbodyarrayThe complete new question set, replacing the old one. Pass [] to empty the draft

Response

FieldTypeAlwaysDescription
idstringSurvey id
namestringWhat this survey is called
statusstringdraft: editable, not answerable. published: answerable, frozen. archived: terminal, neither editable nor answerable, and there is no way back
createdAtstringISO-8601 creation timestamp
questionsarrayThe ordered question set, exactly as stored
updatedAtstringISO-8601 last-modification timestamp
POST/support/surveys/:id/archive

Switch a survey off for good, from either draft or published. Archiving is terminal — there is no way back in v2 — and it deletes nothing: every response already collected stays readable

MCP tool: support_survey_archive

Parameters

NameInTypeRequiredDescription
idpathstringSurvey id

Response

FieldTypeAlwaysDescription
idstringSurvey id
namestringWhat this survey is called
statusstringdraft: editable, not answerable. published: answerable, frozen. archived: terminal, neither editable nor answerable, and there is no way back
createdAtstringISO-8601 creation timestamp
questionsarrayThe ordered question set, exactly as stored
updatedAtstringISO-8601 last-modification timestamp
POST/support/surveys/:id/publish

Publish a draft survey, which is what makes it answerable and what freezes its structure. Publishing validates the whole question set: it must be non-empty, question ids must be unique, radio and checkbox questions must offer options, a statement may not be required, and every skip must target a later question or the literal "end". A survey that is already published or archived is refused

MCP tool: support_survey_publish

Parameters

NameInTypeRequiredDescription
idpathstringSurvey id

Response

FieldTypeAlwaysDescription
idstringSurvey id
namestringWhat this survey is called
statusstringdraft: editable, not answerable. published: answerable, frozen. archived: terminal, neither editable nor answerable, and there is no way back
createdAtstringISO-8601 creation timestamp
questionsarrayThe ordered question set, exactly as stored
updatedAtstringISO-8601 last-modification timestamp
GET/support/surveys/:id/stats

Aggregate one survey’s responses over a time window: how many came in and how many reached the end, then per question — option counts for radio and checkbox, mean and distribution for rating and nps, an answered count for the rest. For the FIRST nps question it also returns promoters (9-10), passives (7-8), detractors (0-6) and the NPS score: percentage of promoters minus percentage of detractors over everyone who answered, rounded once. The window defaults to the last 30 days — omitting from does not mean "since the beginning"

MCP tool: support_survey_stats

Parameters

NameInTypeRequiredDescription
idpathstringSurvey id
fromquerystringStart of the window, ISO-8601, inclusive. Defaults to 30 days ago — omitting it means "recently", never "since the beginning"
toquerystringEnd of the window, ISO-8601, inclusive. Defaults to now

Response

FieldTypeAlwaysDescription
tostringISO-8601 end of the window that was actually applied
npsobjectThe NPS block, or null when the survey asks no nps question
fromstringISO-8601 start of the window that was actually applied
surveyIdstringThe survey these numbers describe
questionsarrayEvery question of the survey, answered or not
responsesobjectThe response counts over the window
POST/support/surveys/:id/unpublish

Return a published survey to draft so it can be edited. It stops accepting responses immediately; the responses already collected are untouched. A survey that is not published is refused

MCP tool: support_survey_unpublish

Parameters

NameInTypeRequiredDescription
idpathstringSurvey id

Response

FieldTypeAlwaysDescription
idstringSurvey id
namestringWhat this survey is called
statusstringdraft: editable, not answerable. published: answerable, frozen. archived: terminal, neither editable nor answerable, and there is no way back
createdAtstringISO-8601 creation timestamp
questionsarrayThe ordered question set, exactly as stored
updatedAtstringISO-8601 last-modification timestamp
GET/support/threads

List support threads for this product, newest first — by creation time by default, or by last modification with sort='updated'. Every filter lives here: type, status, status category, assignee, external author, creation window, rating range (ratingMin/ratingMax, inclusive — a thread nobody rated matches neither bound), plus pagination

MCP tool: support_thread_list

Parameters

NameInTypeRequiredDescription
typequerystringOnly threads of this type
statusIdquerystringOnly threads sitting on this exact status
categoryquerystringOnly threads whose status belongs to this category. Resolved through a join on the status dictionary — the category is never stored on the thread
assignedAgentIdquerystringOnly threads assigned to this agent
authorExternalIdquerystringOnly threads opened by this external author, matched verbatim
createdFromquerystringOnly threads created at or after this ISO-8601 timestamp
createdToquerystringOnly threads created at or before this ISO-8601 timestamp
ratingMinqueryintegerOnly threads rated at or above this score (0..10, inclusive). An unrated thread never matches a rating filter — not even at the bottom of the scale
ratingMaxqueryintegerOnly threads rated at or below this score (0..10, inclusive). An unrated thread never matches a rating filter — not even at the bottom of the scale
labelIdsquerystringOnly threads carrying ALL of these labels. Every other filter here narrows the result and so does this one: each additional label id makes the answer smaller, never bigger
sortquerystringOrdering of the page, newest first either way (default 'created')
limitqueryintegerPage size, 1..100 (default 25)
offsetqueryintegerNumber of threads to skip

Response

FieldTypeAlwaysDescription
limitintegerPage size that was applied
offsetintegerOffset that was applied
threadsarrayThe requested page of threads, newest first by the requested sort
POST/support/threads

Open a support thread on behalf of an external end user. The author is an opaque identifier from the client's own user base and is stored verbatim. The thread opens on the product's default open status; there is no status argument. An optional rating — an integer 0..10, both ends inclusive — may travel with it and is stored verbatim too; omit it for an unrated thread, because 0 is a real score at the bottom of the scale

MCP tool: support_thread_create

Parameters

NameInTypeRequiredDescription
typebodystringticket: the end user wants something fixed. feedback: unsolicited input
titlebodystringShort human-readable subject of the thread
authorExternalIdbodystringOpaque identifier of the external end user in the client's own user base. Stored verbatim: never resolved, normalised or enriched, and it is not a Lessly identity
authorDisplaybodystringOptional display name for the external author, as the client already knows it
metadatabodyobjectFree-form client-owned JSON attached to the thread
labelIdsbodyarrayLabels to put on the new thread
ratingbodyintegerOptional score the client attached when the thread was opened: an integer 0..10, both ends inclusive, stored verbatim and never recomputed. Omit it for an unrated thread — 0 is a real score at the bottom of the scale, not a way of saying "no rating"

Response

FieldTypeAlwaysDescription
idstringThread id
typestringticket: the end user wants something fixed. feedback: unsolicited input
titlestringThread subject
labelsarrayEvery label on the thread, by name
ratingintegerThe score the client supplied at creation, or null while the thread is unrated
statusobjectThe status itself, joined in at read time
metadataobjectFree-form client-owned JSON
prioritystringThread priority
statusIdstringId of the status the thread sits on
createdAtstringISO-8601 creation timestamp
updatedAtstringISO-8601 last-modification timestamp
lastReplyAtstringISO-8601 timestamp of the last reply, or null while there are none
authorDisplaystringDisplay name for the external author, if given
assignedAgentIdstringAssigned agent, or null while unassigned
authorExternalIdstringThe external author, byte-identical to what was stored
GET/support/threads/:id

Get one support thread by id, with its status joined in. A thread belonging to another product is reported as not found

MCP tool: support_thread_get

Parameters

NameInTypeRequiredDescription
idpathstringThread id

Response

FieldTypeAlwaysDescription
idstringThread id
typestringticket: the end user wants something fixed. feedback: unsolicited input
titlestringThread subject
labelsarrayEvery label on the thread, by name
ratingintegerThe score the client supplied at creation, or null while the thread is unrated
statusobjectThe status itself, joined in at read time
metadataobjectFree-form client-owned JSON
prioritystringThread priority
statusIdstringId of the status the thread sits on
createdAtstringISO-8601 creation timestamp
updatedAtstringISO-8601 last-modification timestamp
lastReplyAtstringISO-8601 timestamp of the last reply, or null while there are none
authorDisplaystringDisplay name for the external author, if given
assignedAgentIdstringAssigned agent, or null while unassigned
authorExternalIdstringThe external author, byte-identical to what was stored
PATCH/support/threads/:id

Edit a thread: its title, its priority, its labels and its client-owned metadata. Moving a thread between statuses and putting an agent on it have their own tools and are not possible here. labelIds replaces the entire label set — pass an empty array to clear it, and a label belonging to another product is reported as not found

MCP tool: support_thread_update

Parameters

NameInTypeRequiredDescription
idpathstringThread id
titlebodystringNew subject of the thread
prioritybodystringNew priority
labelIdsbodyarrayThe complete new label set. Pass an empty array to remove every label
metadatabodyobjectReplaces the whole client-owned metadata object

Response

FieldTypeAlwaysDescription
idstringThread id
typestringticket: the end user wants something fixed. feedback: unsolicited input
titlestringThread subject
labelsarrayEvery label on the thread, by name
ratingintegerThe score the client supplied at creation, or null while the thread is unrated
statusobjectThe status itself, joined in at read time
metadataobjectFree-form client-owned JSON
prioritystringThread priority
statusIdstringId of the status the thread sits on
createdAtstringISO-8601 creation timestamp
updatedAtstringISO-8601 last-modification timestamp
lastReplyAtstringISO-8601 timestamp of the last reply, or null while there are none
authorDisplaystringDisplay name for the external author, if given
assignedAgentIdstringAssigned agent, or null while unassigned
authorExternalIdstringThe external author, byte-identical to what was stored
POST/support/threads/:id/assignment

Put a support agent on a thread, or pass null to return it to the unassigned queue — clearing an assignment is an ordinary operation, not an error. An agent belonging to another product is reported as not found

MCP tool: support_thread_assign

Parameters

NameInTypeRequiredDescription
idpathstringThread id
agentIdbodystringSupport agent of this product to put on the thread, or null to return it to the unassigned queue. An agent of another product is reported as not found

Response

FieldTypeAlwaysDescription
idstringThread id
typestringticket: the end user wants something fixed. feedback: unsolicited input
titlestringThread subject
labelsarrayEvery label on the thread, by name
ratingintegerThe score the client supplied at creation, or null while the thread is unrated
statusobjectThe status itself, joined in at read time
metadataobjectFree-form client-owned JSON
prioritystringThread priority
statusIdstringId of the status the thread sits on
createdAtstringISO-8601 creation timestamp
updatedAtstringISO-8601 last-modification timestamp
lastReplyAtstringISO-8601 timestamp of the last reply, or null while there are none
authorDisplaystringDisplay name for the external author, if given
assignedAgentIdstringAssigned agent, or null while unassigned
authorExternalIdstringThe external author, byte-identical to what was stored
POST/support/threads/:id/status

Move a thread to a status. Any status may follow any other — there are no transition rules. The category is never a parameter: it comes from the status the thread lands on. A status belonging to another product is reported as not found, and an archived status is refused

MCP tool: support_thread_status_set

Parameters

NameInTypeRequiredDescription
idpathstringThread id
statusIdbodystringDestination status of this product. Any status may follow any other — v1 has no transition rules. An archived status is refused

Response

FieldTypeAlwaysDescription
idstringThread id
typestringticket: the end user wants something fixed. feedback: unsolicited input
titlestringThread subject
labelsarrayEvery label on the thread, by name
ratingintegerThe score the client supplied at creation, or null while the thread is unrated
statusobjectThe status itself, joined in at read time
metadataobjectFree-form client-owned JSON
prioritystringThread priority
statusIdstringId of the status the thread sits on
createdAtstringISO-8601 creation timestamp
updatedAtstringISO-8601 last-modification timestamp
lastReplyAtstringISO-8601 timestamp of the last reply, or null while there are none
authorDisplaystringDisplay name for the external author, if given
assignedAgentIdstringAssigned agent, or null while unassigned
authorExternalIdstringThe external author, byte-identical to what was stored
GET/support/webhook-deliveries

List webhook delivery attempts for this product, newest first. Filter by endpoint, by state (pending, delivered, failed), by event type or by the time the delivery was opened. Each row carries the exact JSON body that was sent, the last HTTP status and, while attempts remain, when the next one is due

MCP tool: support_webhook_deliveries_list

Parameters

NameInTypeRequiredDescription
webhookIdquerystringOnly deliveries for this endpoint
statequerystringOnly deliveries in this state: pending, delivered or failed
eventTypequerystringOnly deliveries of this event type
createdFromquerystringOnly deliveries opened at or after this ISO-8601 time
createdToquerystringOnly deliveries opened at or before this ISO-8601 time
limitqueryintegerPage size, 1..200 (default 50)
offsetqueryintegerNumber of deliveries to skip

Response

FieldTypeAlwaysDescription
limitintegerPage size that was applied
offsetintegerOffset that was applied
deliveriesarrayThe requested page, newest first
POST/support/webhook-deliveries/redeliver

Send a past delivery to its endpoint again, with the original payload and the original idempotencyKey — a receiver that already processed it can recognise and ignore the repeat. The original delivery row is kept as history and a new one is opened for this attempt. If the endpoint has since been disabled or unsubscribed from the event, nothing is delivered

MCP tool: support_webhook_redeliver

Parameters

NameInTypeRequiredDescription
idbodystringId of the delivery to send again

Response

FieldTypeAlwaysDescription
deliveryobjectThe new delivery, opened in pending state. It carries the original idempotencyKey, so a receiver that already processed the first one can ignore it
GET/support/webhooks

List the endpoints this product has registered, oldest first. Signing secrets are never included — only the short prefix that tells two endpoints apart

MCP tool: support_webhook_list

Parameters

No parameters.

Response

FieldTypeAlwaysDescription
webhooksarrayThe endpoints this product has registered, oldest first
POST/support/webhooks

Register an HTTPS endpoint to receive Support events for this product, and mint its signing secret. The secret is returned here in clear and NOWHERE ELSE — exactly once, so store it now: it cannot be read back and can only be replaced by rotating it. Plain http:// endpoints are rejected

MCP tool: support_webhook_create

Parameters

NameInTypeRequiredDescription
urlbodystringHTTPS endpoint the event is POSTed to. Plain http:// is rejected
eventTypesbodyarrayEvent types this endpoint subscribes to. One or more of support.message.created, support.thread.status-changed, support.thread.assigned, support.survey.published, support.response.created
descriptionbodystringFree-form note about what this endpoint is for, up to 1000 characters

Response

FieldTypeAlwaysDescription
idstringWebhook id
urlstringHTTPS endpoint events are POSTed to
secretstringThe signing secret in clear. Shown exactly once, here — store it now; it cannot be read back and can only be replaced by rotating it
statusstringactive or disabled
createdAtstringISO-8601 creation timestamp
updatedAtstringISO-8601 last-update timestamp
eventTypesarrayEvent types this endpoint subscribes to
descriptionstringFree-form note, or null
secretPrefixstringFirst characters of the signing secret, to tell endpoints apart. Never the whole secret
DELETE/support/webhooks/:id

Remove a registered endpoint and the delivery history that points at it. To stop delivery without losing the registration, set its status to disabled instead

MCP tool: support_webhook_delete

Parameters

NameInTypeRequiredDescription
idpathstringWebhook id

Response

FieldTypeAlwaysDescription
idstringId of the endpoint that was removed
deletedbooleanAlways true — the endpoint is gone
GET/support/webhooks/:id

Get one registered endpoint by id. The signing secret is not part of the answer. An endpoint belonging to another product is reported as not found

MCP tool: support_webhook_get

Parameters

NameInTypeRequiredDescription
idpathstringWebhook id

Response

FieldTypeAlwaysDescription
idstringWebhook id
urlstringHTTPS endpoint events are POSTed to
statusstringactive or disabled
createdAtstringISO-8601 creation timestamp
updatedAtstringISO-8601 last-update timestamp
eventTypesarrayEvent types this endpoint subscribes to
descriptionstringFree-form note, or null
secretPrefixstringFirst characters of the signing secret, to tell endpoints apart. Never the whole secret
PATCH/support/webhooks/:id

Edit a registered endpoint: its url, the event types it subscribes to, its description or its status. Setting status to disabled keeps the registration and stops delivery. Omit a field to leave it alone; pass null to clear the description. The signing secret is not editable here — rotate it instead

MCP tool: support_webhook_update

Parameters

NameInTypeRequiredDescription
urlbodystringHTTPS endpoint the event is POSTed to. Plain http:// is rejected
eventTypesbodyarrayEvent types this endpoint subscribes to. One or more of support.message.created, support.thread.status-changed, support.thread.assigned, support.survey.published, support.response.created
descriptionbodystringFree-form note about what this endpoint is for, up to 1000 characters
statusbodystringactive delivers events; disabled keeps the registration and stops delivery
idpathstringWebhook id

Response

FieldTypeAlwaysDescription
idstringWebhook id
urlstringHTTPS endpoint events are POSTed to
statusstringactive or disabled
createdAtstringISO-8601 creation timestamp
updatedAtstringISO-8601 last-update timestamp
eventTypesarrayEvent types this endpoint subscribes to
descriptionstringFree-form note, or null
secretPrefixstringFirst characters of the signing secret, to tell endpoints apart. Never the whole secret
POST/support/webhooks/:id/rotate-secret

Replace the signing secret of an endpoint and return the new one in clear, exactly once. The old secret stops verifying immediately — there is no grace window, so update the receiver before rotating

MCP tool: support_webhook_rotate_secret

Parameters

NameInTypeRequiredDescription
idpathstringWebhook id

Response

FieldTypeAlwaysDescription
idstringWebhook id
urlstringHTTPS endpoint events are POSTed to
secretstringThe signing secret in clear. Shown exactly once, here — store it now; it cannot be read back and can only be replaced by rotating it
statusstringactive or disabled
createdAtstringISO-8601 creation timestamp
updatedAtstringISO-8601 last-update timestamp
eventTypesarrayEvent types this endpoint subscribes to
descriptionstringFree-form note, or null
secretPrefixstringFirst characters of the signing secret, to tell endpoints apart. Never the whole secret
Was this page helpful?
Esc

Start typing to search the docs.

navigateselect