Skip to content
Dashboard

Reply to a ticket

POST/v2/tickets/{id}/reply

Adds a reply to a ticket’s linked conversation. Supports both contact and admin replies.

Path Parameters

  • id - The ticket number

Contact Reply

FieldTypeRequiredDescription
typestringYesMust be “contact”
contactIdstringNo*Featurebase contact ID
contactEmailstringNo*Contact email
bodystringYesMessage content (HTML)
messageTypestringNoAlways “comment” for contacts
attachmentUrlsstring[]NoAttachment URLs (max 10)
skipNotificationsbooleanNoSkip notifications (default false)
createdAtstringNoISO 8601 timestamp to backdate the reply

*At least one of contactId or contactEmail is required.

Admin Reply

FieldTypeRequiredDescription
typestringYesMust be “admin”
adminIdstringYesID of the admin authoring the reply
bodystringYesMessage content (HTML)
messageTypestringNo”comment” (default) or “note” for internal notes
attachmentUrlsstring[]NoAttachment URLs (max 10)
skipNotificationsbooleanNoSkip notifications (default false)
createdAtstringNoISO 8601 timestamp to backdate the reply

Response

Returns a reply confirmation object.

Path ParametersExpand Collapse
id: number
minimum1
Header ParametersExpand Collapse
"Featurebase-Version": optional "2026-01-01.nova" or "2025-12-12.clover"
One of the following:
"2026-01-01.nova"
"2025-12-12.clover"
Body ParametersJSONExpand Collapse
body: object { body, type, attachmentUrls, 5 more } or object { adminId, body, type, 4 more }
One of the following:
object { body, type, attachmentUrls, 5 more }
body: string
minLength1
type: "contact"
attachmentUrls: optional array of string
contactEmail: optional string
formatemail
contactId: optional string
createdAt: optional string
messageType: optional "comment"
skipNotifications: optional boolean
object { adminId, body, type, 4 more }
adminId: string
body: string
minLength1
type: "admin"
attachmentUrls: optional array of string
createdAt: optional string
messageType: optional "comment" or "note"
One of the following:
"comment"
"note"
skipNotifications: optional boolean
ReturnsExpand Collapse
Ticket object { id, assigneeId, author, 18 more }
id: string

Unique identifier (MongoDB ID)

assigneeId: string

Assigned admin ID

author: object { id, email, name, 2 more }

Contact who created the ticket

id: string

Author unique identifier

email: string

Author email

name: string

Author display name

profilePicture: string

Author profile picture URL

type: "admin" or "customer" or "guest" or 3 more

Type of user

One of the following:
"admin"
"customer"
"guest"
"integration"
"bot"
"lead"
categoryType: "customer" or "tracker" or "back-office"

Ticket category type

One of the following:
"customer"
"tracker"
"back-office"
companyId: string

Associated company ID

content: string

Ticket content/description (HTML)

createdAt: string

ISO 8601 creation timestamp

customFields: map[unknown]

Custom field values keyed by field ID. File-type fields contain a JSON string of { key, name, url } with a signed download URL (1 hour expiry). For allowMultiple file fields, the value is a JSON string of an array of these objects.

integrations: object { clickup, devops, github, 3 more }

Third-party integration links

clickup: array of object { id, title, url }
id: string

ClickUp task ID

title: string

ClickUp task title

url: string

URL to the ClickUp task

devops: array of object { id, projectId, projectName, 2 more }
id: number

Azure DevOps work item ID

projectId: string

Azure DevOps project ID

projectName: string

Azure DevOps project name

title: string

Work item title

url: string

URL to the work item

github: array of object { id, number, repositoryFullName, 3 more }
id: string

GitHub issue ID

number: string

GitHub issue number

repositoryFullName: string

Full repository name (owner/repo)

repositoryName: string

Repository name

title: string

GitHub issue title

url: string

URL to the GitHub issue

hubspot: array of object { dealAmount, dealClosed, objectId, type }
dealAmount: number

Deal amount (for DEAL type)

dealClosed: boolean

Whether the deal is closed (for DEAL type)

objectId: number

HubSpot object ID

type: "TICKET" or "DEAL" or "CONTACT"

HubSpot object type

One of the following:
"TICKET"
"DEAL"
"CONTACT"
jira: array of object { issueId, issueUrl }
issueId: string

Jira issue ID

issueUrl: string

URL to the Jira issue

linear: array of object { issueId, issueUrl }
issueId: string

Linear issue ID

issueUrl: string

URL to the Linear issue

linkedConversations: array of object { id, role }

Linked conversations

id: string

Conversation ID

role: "customer" or "tracker" or "back-office"

Link role

One of the following:
"customer"
"tracker"
"back-office"
object: "ticket"

Object type identifier

open: boolean

Whether the ticket is open

snoozedUntil: string

ISO 8601 timestamp until snoozed (from linked conversation)

status: PostStatus { id, color, isDefault, 3 more }

Current ticket status

id: string

Unique identifier

color: string

Color for UI display

isDefault: boolean

Whether this is the default status for new posts

name: string

Display name

object: "post_status"

Object type identifier

type: "reviewing" or "unstarted" or "active" or 2 more

The workflow stage this status represents

One of the following:
"reviewing"
"unstarted"
"active"
"completed"
"canceled"
teamAssigneeId: string

Assigned team ID (from linked conversation)

ticketCategoryId: string

Ticket category ID

ticketNumber: number

Sequential display ID (e.g. TK-42)

ticketUrl: string

Full URL to view the ticket

title: string

Ticket title

updatedAt: string

ISO 8601 last updated timestamp

conversationParts: optional array of ConversationPart

Conversation message history. Only included when fetching a single ticket by ID.

One of the following:
UserMsg object { id, bodyHtml, bodyMarkdown, 8 more }

Message from a customer or lead

id: string

Unique part identifier

bodyHtml: string

Message body content as HTML with signed image URLs

bodyMarkdown: string

Message body content as markdown

channel: "unknown" or "desktop" or "android" or 2 more

Channel through which the message was sent

One of the following:
"unknown"
"desktop"
"android"
"ios"
"email"
createdAt: string

ISO timestamp when the part was created

object: "conversation_part"

Object type identifier

partType: "user_msg"

User message type

updatedAt: string

ISO timestamp when the part was last updated

author: optional ConversationPartAuthor { id, type, email, 2 more }
id: string

Author ID

type: "customer" or "lead" or "admin" or 3 more

Type of author

One of the following:
"customer"
"lead"
"admin"
"bot"
"guest"
"integration"
email: optional string

Author email address

name: optional string

Author display name

profilePicture: optional string

Author profile picture URL

redacted: optional boolean

Whether this message has been redacted

tagApplications: optional array of ConversationTagApplication { appliedAt, tagId, appliedBy, 3 more }

Reply-level tag applications and provenance for this conversation part

appliedAt: string

ISO timestamp when the tag was applied to this reply

tagId: string

Identifier of the applied tag

appliedBy: optional ConversationTagMutationActor { type, id, name }

Actor that applied the tag

type: "admin" or "customer" or "lead" or 4 more

Actor that caused the tag mutation

One of the following:
"admin"
"customer"
"lead"
"bot"
"integration"
"system"
"workflow"
id: optional string

Actor identifier when available

name: optional string

Actor display name when available

removedAt: optional string

ISO timestamp when the tag was removed from this reply, if it was removed

removedBy: optional ConversationTagMutationActor { type, id, name }

Actor that applied the tag

type: "admin" or "customer" or "lead" or 4 more

Actor that caused the tag mutation

One of the following:
"admin"
"customer"
"lead"
"bot"
"integration"
"system"
"workflow"
id: optional string

Actor identifier when available

name: optional string

Actor display name when available

tag: optional ConversationTag { id, name, type }

Resolved tag object when the tag still exists in the shared workspace catalog

id: string

Unique tag identifier

name: string

Current tag name

type: "tag"

Object type identifier for a tag

AdminMsg object { id, bodyHtml, bodyMarkdown, 8 more }

Message from an admin or support agent

id: string

Unique part identifier

bodyHtml: string

Message body content as HTML with signed image URLs

bodyMarkdown: string

Message body content as markdown

channel: "unknown" or "desktop" or "android" or 2 more

Channel through which the message was sent

One of the following:
"unknown"
"desktop"
"android"
"ios"
"email"
createdAt: string

ISO timestamp when the part was created

object: "conversation_part"

Object type identifier

partType: "admin_msg"

Admin message type

updatedAt: string

ISO timestamp when the part was last updated

author: optional ConversationPartAuthor { id, type, email, 2 more }
id: string

Author ID

type: "customer" or "lead" or "admin" or 3 more

Type of author

One of the following:
"customer"
"lead"
"admin"
"bot"
"guest"
"integration"
email: optional string

Author email address

name: optional string

Author display name

profilePicture: optional string

Author profile picture URL

redacted: optional boolean

Whether this message has been redacted

tagApplications: optional array of ConversationTagApplication { appliedAt, tagId, appliedBy, 3 more }

Reply-level tag applications and provenance for this conversation part

appliedAt: string

ISO timestamp when the tag was applied to this reply

tagId: string

Identifier of the applied tag

appliedBy: optional ConversationTagMutationActor { type, id, name }

Actor that applied the tag

type: "admin" or "customer" or "lead" or 4 more

Actor that caused the tag mutation

One of the following:
"admin"
"customer"
"lead"
"bot"
"integration"
"system"
"workflow"
id: optional string

Actor identifier when available

name: optional string

Actor display name when available

removedAt: optional string

ISO timestamp when the tag was removed from this reply, if it was removed

removedBy: optional ConversationTagMutationActor { type, id, name }

Actor that applied the tag

type: "admin" or "customer" or "lead" or 4 more

Actor that caused the tag mutation

One of the following:
"admin"
"customer"
"lead"
"bot"
"integration"
"system"
"workflow"
id: optional string

Actor identifier when available

name: optional string

Actor display name when available

tag: optional ConversationTag { id, name, type }

Resolved tag object when the tag still exists in the shared workspace catalog

id: string

Unique tag identifier

name: string

Current tag name

type: "tag"

Object type identifier for a tag

AdminNote object { id, bodyHtml, bodyMarkdown, 7 more }

Internal note visible only to admins

id: string

Unique part identifier

bodyHtml: string

Note body content as HTML with signed image URLs

bodyMarkdown: string

Note body content as markdown

createdAt: string

ISO timestamp when the part was created

object: "conversation_part"

Object type identifier

partType: "admin_note"

Admin internal note type

updatedAt: string

ISO timestamp when the part was last updated

author: optional ConversationPartAuthor { id, type, email, 2 more }
id: string

Author ID

type: "customer" or "lead" or "admin" or 3 more

Type of author

One of the following:
"customer"
"lead"
"admin"
"bot"
"guest"
"integration"
email: optional string

Author email address

name: optional string

Author display name

profilePicture: optional string

Author profile picture URL

redacted: optional boolean

Whether this message has been redacted

tagApplications: optional array of ConversationTagApplication { appliedAt, tagId, appliedBy, 3 more }

Reply-level tag applications and provenance for this conversation part

appliedAt: string

ISO timestamp when the tag was applied to this reply

tagId: string

Identifier of the applied tag

appliedBy: optional ConversationTagMutationActor { type, id, name }

Actor that applied the tag

type: "admin" or "customer" or "lead" or 4 more

Actor that caused the tag mutation

One of the following:
"admin"
"customer"
"lead"
"bot"
"integration"
"system"
"workflow"
id: optional string

Actor identifier when available

name: optional string

Actor display name when available

removedAt: optional string

ISO timestamp when the tag was removed from this reply, if it was removed

removedBy: optional ConversationTagMutationActor { type, id, name }

Actor that applied the tag

type: "admin" or "customer" or "lead" or 4 more

Actor that caused the tag mutation

One of the following:
"admin"
"customer"
"lead"
"bot"
"integration"
"system"
"workflow"
id: optional string

Actor identifier when available

name: optional string

Actor display name when available

tag: optional ConversationTag { id, name, type }

Resolved tag object when the tag still exists in the shared workspace catalog

id: string

Unique tag identifier

name: string

Current tag name

type: "tag"

Object type identifier for a tag

EmailMsg object { id, bodyHtml, bodyMarkdown, 8 more }

Message sent via email

id: string

Unique part identifier

bodyHtml: string

Email body content as HTML with signed image URLs

bodyMarkdown: string

Email body content as markdown

channel: "email"

Email channel

createdAt: string

ISO timestamp when the part was created

object: "conversation_part"

Object type identifier

partType: "email_msg"

Email message type

updatedAt: string

ISO timestamp when the part was last updated

author: optional ConversationPartAuthor { id, type, email, 2 more }
id: string

Author ID

type: "customer" or "lead" or "admin" or 3 more

Type of author

One of the following:
"customer"
"lead"
"admin"
"bot"
"guest"
"integration"
email: optional string

Author email address

name: optional string

Author display name

profilePicture: optional string

Author profile picture URL

redacted: optional boolean

Whether this message has been redacted

tagApplications: optional array of ConversationTagApplication { appliedAt, tagId, appliedBy, 3 more }

Reply-level tag applications and provenance for this conversation part

appliedAt: string

ISO timestamp when the tag was applied to this reply

tagId: string

Identifier of the applied tag

appliedBy: optional ConversationTagMutationActor { type, id, name }

Actor that applied the tag

type: "admin" or "customer" or "lead" or 4 more

Actor that caused the tag mutation

One of the following:
"admin"
"customer"
"lead"
"bot"
"integration"
"system"
"workflow"
id: optional string

Actor identifier when available

name: optional string

Actor display name when available

removedAt: optional string

ISO timestamp when the tag was removed from this reply, if it was removed

removedBy: optional ConversationTagMutationActor { type, id, name }

Actor that applied the tag

type: "admin" or "customer" or "lead" or 4 more

Actor that caused the tag mutation

One of the following:
"admin"
"customer"
"lead"
"bot"
"integration"
"system"
"workflow"
id: optional string

Actor identifier when available

name: optional string

Actor display name when available

tag: optional ConversationTag { id, name, type }

Resolved tag object when the tag still exists in the shared workspace catalog

id: string

Unique tag identifier

name: string

Current tag name

type: "tag"

Object type identifier for a tag

BotMsg object { id, bodyHtml, bodyMarkdown, 8 more }

Automated message from AI or bot

id: string

Unique part identifier

bodyHtml: string

Bot message body content as HTML with signed image URLs

bodyMarkdown: string

Bot message body content as markdown

createdAt: string

ISO timestamp when the part was created

object: "conversation_part"

Object type identifier

partType: "bot_msg"

Bot message type

updatedAt: string

ISO timestamp when the part was last updated

author: optional ConversationPartAuthor { id, type, email, 2 more }
id: string

Author ID

type: "customer" or "lead" or "admin" or 3 more

Type of author

One of the following:
"customer"
"lead"
"admin"
"bot"
"guest"
"integration"
email: optional string

Author email address

name: optional string

Author display name

profilePicture: optional string

Author profile picture URL

channel: optional "unknown" or "desktop" or "android" or 2 more

Channel through which the message was sent

One of the following:
"unknown"
"desktop"
"android"
"ios"
"email"
redacted: optional boolean

Whether this message has been redacted

tagApplications: optional array of ConversationTagApplication { appliedAt, tagId, appliedBy, 3 more }

Reply-level tag applications and provenance for this conversation part

appliedAt: string

ISO timestamp when the tag was applied to this reply

tagId: string

Identifier of the applied tag

appliedBy: optional ConversationTagMutationActor { type, id, name }

Actor that applied the tag

type: "admin" or "customer" or "lead" or 4 more

Actor that caused the tag mutation

One of the following:
"admin"
"customer"
"lead"
"bot"
"integration"
"system"
"workflow"
id: optional string

Actor identifier when available

name: optional string

Actor display name when available

removedAt: optional string

ISO timestamp when the tag was removed from this reply, if it was removed

removedBy: optional ConversationTagMutationActor { type, id, name }

Actor that applied the tag

type: "admin" or "customer" or "lead" or 4 more

Actor that caused the tag mutation

One of the following:
"admin"
"customer"
"lead"
"bot"
"integration"
"system"
"workflow"
id: optional string

Actor identifier when available

name: optional string

Actor display name when available

tag: optional ConversationTag { id, name, type }

Resolved tag object when the tag still exists in the shared workspace catalog

id: string

Unique tag identifier

name: string

Current tag name

type: "tag"

Object type identifier for a tag

QuickReplyOpts object { id, createdAt, object, 6 more }

Presents options for user to choose from

id: string

Unique part identifier

createdAt: string

ISO timestamp when the part was created

object: "conversation_part"

Object type identifier

partType: "quick_reply_opts"

Quick reply options type

replyOptions: array of object { id, text }

Available reply options

id: string

Option ID

text: string

Option text

updatedAt: string

ISO timestamp when the part was last updated

author: optional ConversationPartAuthor { id, type, email, 2 more }
id: string

Author ID

type: "customer" or "lead" or "admin" or 3 more

Type of author

One of the following:
"customer"
"lead"
"admin"
"bot"
"guest"
"integration"
email: optional string

Author email address

name: optional string

Author display name

profilePicture: optional string

Author profile picture URL

redacted: optional boolean

Whether this message has been redacted

tagApplications: optional array of ConversationTagApplication { appliedAt, tagId, appliedBy, 3 more }

Reply-level tag applications and provenance for this conversation part

appliedAt: string

ISO timestamp when the tag was applied to this reply

tagId: string

Identifier of the applied tag

appliedBy: optional ConversationTagMutationActor { type, id, name }

Actor that applied the tag

type: "admin" or "customer" or "lead" or 4 more

Actor that caused the tag mutation

One of the following:
"admin"
"customer"
"lead"
"bot"
"integration"
"system"
"workflow"
id: optional string

Actor identifier when available

name: optional string

Actor display name when available

removedAt: optional string

ISO timestamp when the tag was removed from this reply, if it was removed

removedBy: optional ConversationTagMutationActor { type, id, name }

Actor that applied the tag

type: "admin" or "customer" or "lead" or 4 more

Actor that caused the tag mutation

One of the following:
"admin"
"customer"
"lead"
"bot"
"integration"
"system"
"workflow"
id: optional string

Actor identifier when available

name: optional string

Actor display name when available

tag: optional ConversationTag { id, name, type }

Resolved tag object when the tag still exists in the shared workspace catalog

id: string

Unique tag identifier

name: string

Current tag name

type: "tag"

Object type identifier for a tag

QuickReplyResp object { id, bodyHtml, bodyMarkdown, 8 more }

User’s selection from quick reply options

id: string

Unique part identifier

bodyHtml: string

The selected option text as HTML

bodyMarkdown: string

The selected option text as markdown

createdAt: string

ISO timestamp when the part was created

object: "conversation_part"

Object type identifier

partType: "quick_reply_resp"

Quick reply response type

selectedOptionId: string

ID of the selected option

updatedAt: string

ISO timestamp when the part was last updated

author: optional ConversationPartAuthor { id, type, email, 2 more }
id: string

Author ID

type: "customer" or "lead" or "admin" or 3 more

Type of author

One of the following:
"customer"
"lead"
"admin"
"bot"
"guest"
"integration"
email: optional string

Author email address

name: optional string

Author display name

profilePicture: optional string

Author profile picture URL

redacted: optional boolean

Whether this message has been redacted

tagApplications: optional array of ConversationTagApplication { appliedAt, tagId, appliedBy, 3 more }

Reply-level tag applications and provenance for this conversation part

appliedAt: string

ISO timestamp when the tag was applied to this reply

tagId: string

Identifier of the applied tag

appliedBy: optional ConversationTagMutationActor { type, id, name }

Actor that applied the tag

type: "admin" or "customer" or "lead" or 4 more

Actor that caused the tag mutation

One of the following:
"admin"
"customer"
"lead"
"bot"
"integration"
"system"
"workflow"
id: optional string

Actor identifier when available

name: optional string

Actor display name when available

removedAt: optional string

ISO timestamp when the tag was removed from this reply, if it was removed

removedBy: optional ConversationTagMutationActor { type, id, name }

Actor that applied the tag

type: "admin" or "customer" or "lead" or 4 more

Actor that caused the tag mutation

One of the following:
"admin"
"customer"
"lead"
"bot"
"integration"
"system"
"workflow"
id: optional string

Actor identifier when available

name: optional string

Actor display name when available

tag: optional ConversationTag { id, name, type }

Resolved tag object when the tag still exists in the shared workspace catalog

id: string

Unique tag identifier

name: string

Current tag name

type: "tag"

Object type identifier for a tag

RatingRequested object { id, createdAt, csat, 3 more }

Represents a persisted CSAT request in the conversation thread

id: string

Unique part identifier

createdAt: string

ISO timestamp when the part was created

csat: object { channel, requestedAt, requestId, 7 more }

Canonical CSAT request payload for this thread event

channel: "desktop" or "email"

Channel used for the CSAT request

One of the following:
"desktop"
"email"
requestedAt: string

ISO timestamp when the request was created

requestId: string

Canonical CSAT request ID

requestSource: "workflow"

Source that created the CSAT request

status: "pending" or "rated" or "canceled" or "expired"

Status of the CSAT request represented by this part

One of the following:
"pending"
"rated"
"canceled"
"expired"
changeLockWindowEndsAt: optional string

ISO timestamp after which changing the rating is no longer allowed

expiredAt: optional string

ISO timestamp when the request expired, when applicable

lateSubmitWindowEndsAt: optional string

ISO timestamp after which late submission is no longer allowed

ratedAgent: optional CsatRatedAgent { type, id }
type: "teammate" or "fibi" or "chatbot"

Type of agent the CSAT request is attributed to

One of the following:
"teammate"
"fibi"
"chatbot"
id: optional string

Identifier of the rated agent when applicable

workflow: optional CsatWorkflowLink { workflowActionId, workflowId, workflowRunId, workflowStepId }
object: "conversation_part"

Object type identifier

partType: "rating_requested"

CSAT rating requested part type

updatedAt: string

ISO timestamp when the part was last updated

RatingSubmitted object { id, createdAt, csat, 3 more }

Represents a persisted CSAT submission in the conversation thread

id: string

Unique part identifier

createdAt: string

ISO timestamp when the part was created

csat: object { channel, ratedAt, requestId, 7 more }

Canonical CSAT submission payload for this thread event

channel: "desktop" or "email"

Channel used for the CSAT request

One of the following:
"desktop"
"email"
ratedAt: string

ISO timestamp when the customer submitted the rating

requestId: string

Canonical CSAT request ID

requestSource: "workflow"

Source that created the CSAT request

score: number

CSAT score from 1 to 5

minimum1
maximum5
status: "rated"

Submitted ratings are always in the rated state

ratedAgent: optional CsatRatedAgent { type, id }
type: "teammate" or "fibi" or "chatbot"

Type of agent the CSAT request is attributed to

One of the following:
"teammate"
"fibi"
"chatbot"
id: optional string

Identifier of the rated agent when applicable

remark: optional string

Optional remark left with the rating

requestedAt: optional string

ISO timestamp when the request was created

workflow: optional CsatWorkflowLink { workflowActionId, workflowId, workflowRunId, workflowStepId }
object: "conversation_part"

Object type identifier

partType: "rating_submitted"

CSAT rating submitted part type

updatedAt: string

ISO timestamp when the part was last updated

AttrPrompt object { id, createdAt, form, 6 more }

Requests information from user via form

id: string

Unique part identifier

createdAt: string

ISO timestamp when the part was created

form: object { id, attributes }

Form configuration

id: string

Form ID

attributes: array of object { identifier, name, type }

Form fields

identifier: string

Field identifier

name: string

Field display name

type: string

Field type

object: "conversation_part"

Object type identifier

partType: "attr_prompt"

Attribute collection prompt type

updatedAt: string

ISO timestamp when the part was last updated

author: optional ConversationPartAuthor { id, type, email, 2 more }
id: string

Author ID

type: "customer" or "lead" or "admin" or 3 more

Type of author

One of the following:
"customer"
"lead"
"admin"
"bot"
"guest"
"integration"
email: optional string

Author email address

name: optional string

Author display name

profilePicture: optional string

Author profile picture URL

redacted: optional boolean

Whether this message has been redacted

tagApplications: optional array of ConversationTagApplication { appliedAt, tagId, appliedBy, 3 more }

Reply-level tag applications and provenance for this conversation part

appliedAt: string

ISO timestamp when the tag was applied to this reply

tagId: string

Identifier of the applied tag

appliedBy: optional ConversationTagMutationActor { type, id, name }

Actor that applied the tag

type: "admin" or "customer" or "lead" or 4 more

Actor that caused the tag mutation

One of the following:
"admin"
"customer"
"lead"
"bot"
"integration"
"system"
"workflow"
id: optional string

Actor identifier when available

name: optional string

Actor display name when available

removedAt: optional string

ISO timestamp when the tag was removed from this reply, if it was removed

removedBy: optional ConversationTagMutationActor { type, id, name }

Actor that applied the tag

type: "admin" or "customer" or "lead" or 4 more

Actor that caused the tag mutation

One of the following:
"admin"
"customer"
"lead"
"bot"
"integration"
"system"
"workflow"
id: optional string

Actor identifier when available

name: optional string

Actor display name when available

tag: optional ConversationTag { id, name, type }

Resolved tag object when the tag still exists in the shared workspace catalog

id: string

Unique tag identifier

name: string

Current tag name

type: "tag"

Object type identifier for a tag

AttrComplete object { id, createdAt, object, 2 more }

Indicates form was completed

id: string

Unique part identifier

createdAt: string

ISO timestamp when the part was created

object: "conversation_part"

Object type identifier

partType: "attr_complete"

Attribute collection complete type

updatedAt: string

ISO timestamp when the part was last updated

Assign object { id, createdAt, object, 5 more }

Conversation assigned to admin or team

id: string

Unique part identifier

createdAt: string

ISO timestamp when the part was created

object: "conversation_part"

Object type identifier

partType: "assign"

Assignment type

updatedAt: string

ISO timestamp when the part was last updated

adminAssigneeId: optional string

ID of the admin assigned to the conversation

adminAssignerId: optional string

ID of the admin who made the assignment

teamAssigneeId: optional string

ID of the team assigned to the conversation

Status object { id, createdAt, object, 4 more }

Conversation state changed (open/closed/snoozed)

id: string

Unique part identifier

createdAt: string

ISO timestamp when the part was created

object: "conversation_part"

Object type identifier

partType: "status"

Status change type

status: "open" or "closed" or "snoozed"

New conversation status

One of the following:
"open"
"closed"
"snoozed"
updatedAt: string

ISO timestamp when the part was last updated

snoozedUntil: optional string

ISO timestamp until conversation is snoozed (if snoozed)

Tags object { id, action, createdAt, 8 more }

A tag was added to or removed from a specific reply

id: string

Unique part identifier

action: "added" or "removed"

Whether the tag was added or removed

One of the following:
"added"
"removed"
createdAt: string

ISO timestamp when the part was created

object: "conversation_part"

Object type identifier

occurredAt: string

ISO timestamp when the tag mutation occurred

partType: "tags"

Tag update type

tagId: string

Identifier of the affected tag

updatedAt: string

ISO timestamp when the part was last updated

actor: optional ConversationTagMutationActor { type, id, name }

Actor that applied the tag

type: "admin" or "customer" or "lead" or 4 more

Actor that caused the tag mutation

One of the following:
"admin"
"customer"
"lead"
"bot"
"integration"
"system"
"workflow"
id: optional string

Actor identifier when available

name: optional string

Actor display name when available

tagName: optional string

Tag name at the time of the event or the best available current display name

targetPartId: optional string

Conversation part that the tag mutation targeted

WorkflowWait object { id, createdAt, object, 3 more }

Represents a workflow wait start, finish, or interruption in the conversation thread

id: string

Unique part identifier

createdAt: string

ISO timestamp when the part was created

object: "conversation_part"

Object type identifier

partType: "workflow_wait"

Workflow wait event part type

updatedAt: string

ISO timestamp when the part was last updated

workflowWait: object { eventType, occurredAt, interruptedByUserType, 3 more }

Workflow wait event payload for this thread event

eventType: "started" or "finished" or "interrupted"

Lifecycle stage of the workflow wait event

One of the following:
"started"
"finished"
"interrupted"
occurredAt: string

ISO timestamp when the wait event occurred

interruptedByUserType: optional "admin" or "customer" or "lead"

User type that interrupted the wait when applicable

One of the following:
"admin"
"customer"
"lead"
waitLabel: optional string

Human-readable wait duration or preset label

workflowId: optional string

Workflow ID associated with the wait event

workflowName: optional string

Workflow display name at the time of the wait event

Priority object { id, createdAt, isPriority, 3 more }

Conversation priority was updated

id: string

Unique part identifier

createdAt: string

ISO timestamp when the part was created

isPriority: boolean

Whether the conversation is now marked as priority

object: "conversation_part"

Object type identifier

partType: "priority"

Priority change type

updatedAt: string

ISO timestamp when the part was last updated

PartAdd object { id, createdAt, object, 3 more }

New participant joined the conversation

id: string

Unique part identifier

createdAt: string

ISO timestamp when the part was created

object: "conversation_part"

Object type identifier

participant: object { id, type }

The added participant

id: string

Participant ID

type: "customer" or "lead" or "admin"

Participant type

One of the following:
"customer"
"lead"
"admin"
partType: "part_add"

Participant added type

updatedAt: string

ISO timestamp when the part was last updated

Reply to a ticket

curl https://do.featurebase.app/v2/tickets/$ID/reply \
    -H 'Content-Type: application/json' \
    -H "Authorization: Bearer $FEATUREBASE_API_KEY" \
    -d '{
          "body": "<p>Thank you for your help!</p>",
          "type": "contact",
          "contactEmail": "john@example.com",
          "contactId": "507f1f77bcf86cd799439011",
          "createdAt": "2025-01-15T10:30:00.000Z",
          "messageType": "comment"
        }'
{
  "id": "507f1f77bcf86cd799439011",
  "assigneeId": "507f1f77bcf86cd799439013",
  "author": {
    "id": "507f1f77bcf86cd799439011",
    "email": "john@example.com",
    "name": "John Doe",
    "profilePicture": "https://cdn.example.com/avatars/john.png",
    "type": "customer"
  },
  "categoryType": "customer",
  "companyId": "507f1f77bcf86cd799439015",
  "content": "<p>I get a 403 error when logging in.</p>",
  "createdAt": "2025-01-15T10:30:00.000Z",
  "customFields": {
    "priority": "bar",
    "507f1f77bcf86cd799439099": "bar"
  },
  "integrations": {
    "clickup": [
      {
        "id": "86a1b2c3d",
        "title": "Fix login bug",
        "url": "https://app.clickup.com/t/86a1b2c3d"
      }
    ],
    "devops": [
      {
        "id": 789,
        "projectId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
        "projectName": "My Project",
        "title": "Implement SSO",
        "url": "https://dev.azure.com/org/project/_workitems/edit/789"
      }
    ],
    "github": [
      {
        "id": "1234567890",
        "number": "42",
        "repositoryFullName": "acme/frontend",
        "repositoryName": "frontend",
        "title": "Login page returns 403",
        "url": "https://github.com/acme/frontend/issues/42"
      }
    ],
    "hubspot": [
      {
        "dealAmount": 5000,
        "dealClosed": false,
        "objectId": 12345,
        "type": "DEAL"
      }
    ],
    "jira": [
      {
        "issueId": "PROJ-456",
        "issueUrl": "https://company.atlassian.net/browse/PROJ-456"
      }
    ],
    "linear": [
      {
        "issueId": "LIN-123",
        "issueUrl": "https://linear.app/team/issue/LIN-123"
      }
    ]
  },
  "linkedConversations": [
    {
      "id": "507f1f77bcf86cd799439011",
      "role": "customer"
    }
  ],
  "object": "ticket",
  "open": true,
  "snoozedUntil": "2025-01-16T09:00:00.000Z",
  "status": {
    "id": "507f1f77bcf86cd799439011",
    "color": "Blue",
    "isDefault": false,
    "name": "In Progress",
    "object": "post_status",
    "type": "active"
  },
  "teamAssigneeId": "507f1f77bcf86cd799439014",
  "ticketCategoryId": "507f1f77bcf86cd799439011",
  "ticketNumber": 42,
  "ticketUrl": "https://feedback.example.com/p/cannot-login",
  "title": "Cannot login to dashboard",
  "updatedAt": "2025-01-15T12:30:00.000Z",
  "conversationParts": [
    {
      "id": "1",
      "bodyHtml": "<p>Hello, I have a question about your product.</p>",
      "bodyMarkdown": "Hello, I have a question about your product.",
      "channel": "desktop",
      "createdAt": "2025-01-15T10:30:00.000Z",
      "object": "conversation_part",
      "partType": "user_msg",
      "updatedAt": "2025-01-15T10:30:00.000Z",
      "author": {
        "id": "676f0f6765bdaa7d7d760f88",
        "type": "customer",
        "email": "john@example.com",
        "name": "John Doe",
        "profilePicture": "https://cdn.example.com/avatars/user.png"
      },
      "redacted": false,
      "tagApplications": [
        {
          "appliedAt": "2025-01-15T10:30:00.000Z",
          "tagId": "67ec1234abcd5678ef901234",
          "appliedBy": {
            "type": "admin",
            "id": "507f1f77bcf86cd799439011",
            "name": "John Doe"
          },
          "removedAt": "2025-01-15T11:00:00.000Z",
          "removedBy": {
            "type": "admin",
            "id": "507f1f77bcf86cd799439011",
            "name": "John Doe"
          },
          "tag": {
            "id": "67ec1234abcd5678ef901234",
            "name": "Churn",
            "type": "tag"
          }
        }
      ]
    }
  ]
}
Returns Examples
{
  "id": "507f1f77bcf86cd799439011",
  "assigneeId": "507f1f77bcf86cd799439013",
  "author": {
    "id": "507f1f77bcf86cd799439011",
    "email": "john@example.com",
    "name": "John Doe",
    "profilePicture": "https://cdn.example.com/avatars/john.png",
    "type": "customer"
  },
  "categoryType": "customer",
  "companyId": "507f1f77bcf86cd799439015",
  "content": "<p>I get a 403 error when logging in.</p>",
  "createdAt": "2025-01-15T10:30:00.000Z",
  "customFields": {
    "priority": "bar",
    "507f1f77bcf86cd799439099": "bar"
  },
  "integrations": {
    "clickup": [
      {
        "id": "86a1b2c3d",
        "title": "Fix login bug",
        "url": "https://app.clickup.com/t/86a1b2c3d"
      }
    ],
    "devops": [
      {
        "id": 789,
        "projectId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
        "projectName": "My Project",
        "title": "Implement SSO",
        "url": "https://dev.azure.com/org/project/_workitems/edit/789"
      }
    ],
    "github": [
      {
        "id": "1234567890",
        "number": "42",
        "repositoryFullName": "acme/frontend",
        "repositoryName": "frontend",
        "title": "Login page returns 403",
        "url": "https://github.com/acme/frontend/issues/42"
      }
    ],
    "hubspot": [
      {
        "dealAmount": 5000,
        "dealClosed": false,
        "objectId": 12345,
        "type": "DEAL"
      }
    ],
    "jira": [
      {
        "issueId": "PROJ-456",
        "issueUrl": "https://company.atlassian.net/browse/PROJ-456"
      }
    ],
    "linear": [
      {
        "issueId": "LIN-123",
        "issueUrl": "https://linear.app/team/issue/LIN-123"
      }
    ]
  },
  "linkedConversations": [
    {
      "id": "507f1f77bcf86cd799439011",
      "role": "customer"
    }
  ],
  "object": "ticket",
  "open": true,
  "snoozedUntil": "2025-01-16T09:00:00.000Z",
  "status": {
    "id": "507f1f77bcf86cd799439011",
    "color": "Blue",
    "isDefault": false,
    "name": "In Progress",
    "object": "post_status",
    "type": "active"
  },
  "teamAssigneeId": "507f1f77bcf86cd799439014",
  "ticketCategoryId": "507f1f77bcf86cd799439011",
  "ticketNumber": 42,
  "ticketUrl": "https://feedback.example.com/p/cannot-login",
  "title": "Cannot login to dashboard",
  "updatedAt": "2025-01-15T12:30:00.000Z",
  "conversationParts": [
    {
      "id": "1",
      "bodyHtml": "<p>Hello, I have a question about your product.</p>",
      "bodyMarkdown": "Hello, I have a question about your product.",
      "channel": "desktop",
      "createdAt": "2025-01-15T10:30:00.000Z",
      "object": "conversation_part",
      "partType": "user_msg",
      "updatedAt": "2025-01-15T10:30:00.000Z",
      "author": {
        "id": "676f0f6765bdaa7d7d760f88",
        "type": "customer",
        "email": "john@example.com",
        "name": "John Doe",
        "profilePicture": "https://cdn.example.com/avatars/user.png"
      },
      "redacted": false,
      "tagApplications": [
        {
          "appliedAt": "2025-01-15T10:30:00.000Z",
          "tagId": "67ec1234abcd5678ef901234",
          "appliedBy": {
            "type": "admin",
            "id": "507f1f77bcf86cd799439011",
            "name": "John Doe"
          },
          "removedAt": "2025-01-15T11:00:00.000Z",
          "removedBy": {
            "type": "admin",
            "id": "507f1f77bcf86cd799439011",
            "name": "John Doe"
          },
          "tag": {
            "id": "67ec1234abcd5678ef901234",
            "name": "Churn",
            "type": "tag"
          }
        }
      ]
    }
  ]
}