Skip to content
Dashboard

Create a conversation

POST/v2/conversations

Creates a new conversation. Supports both contact-initiated (customer/lead) and admin-initiated (outreach) conversations.

Contact-Initiated Conversation

For conversations started by a customer or lead:

FieldTypeRequiredDescription
from.typestringYesMust be “contact”
from.idstringYesThe Featurebase contact ID (24-character ObjectId)
bodyMarkdownstringYesThe initial message content in markdown format. Images referenced by URL or as base64 data URIs will be automatically uploaded and stored.
channelstringNoThe channel: “desktop” (default) or “email”
createdAtstringNoISO timestamp for migrations

Example Contact-Initiated Request

{
  "from": {
    "type": "contact",
    "id": "676f0f6765bdaa7d7d760f88"
  },
  "bodyMarkdown": "Hello, I have a question about your product.",
  "channel": "desktop"
}

Admin-Initiated Outreach

For outreach conversations started by an admin:

FieldTypeRequiredDescription
from.typestringYesMust be “admin”
from.idstringYesThe Featurebase admin ID (24-character ObjectId)
bodyMarkdownstringYesThe initial message content in markdown format. Images referenced by URL or as base64 data URIs will be automatically uploaded and stored.
channelstringNoThe channel: “desktop” (default) or “email”
recipientsobjectYesRecipients for the outreach
recipients.toobjectYesPrimary recipients
recipients.to.emailsstring[]No*Email addresses
recipients.to.idsstring[]No*Featurebase contact IDs
recipients.ccobjectNoCC recipients (same structure as “to”)
recipients.bccobjectNoBCC recipients (same structure as “to”)
subjectstringNo**Email subject line
createdAtstringNoISO timestamp for migrations

*At least one email or ID is required in recipients.to **Required when channel is “email”

Example Admin Outreach (In-App)

{
  "from": {
    "type": "admin",
    "id": "507f1f77bcf86cd799439011"
  },
  "bodyMarkdown": "Hi! Just following up on your inquiry.",
  "channel": "desktop",
  "recipients": {
    "to": {
      "ids": ["676f0f6765bdaa7d7d760f88"]
    }
  }
}

Example Admin Outreach (Email)

{
  "from": {
    "type": "admin",
    "id": "507f1f77bcf86cd799439011"
  },
  "bodyMarkdown": "Hi! Just following up on your inquiry.",
  "channel": "email",
  "subject": "Following up on your inquiry",
  "recipients": {
    "to": {
      "emails": ["john@example.com"]
    },
    "cc": {
      "emails": ["manager@example.com"]
    }
  }
}

Response

Returns the created conversation object with a 201 Created status.

Example Response

{
  "object": "conversation",
  "id": "12345",
  "state": "open",
  "priority": false,
  "adminAssigneeId": null,
  "participants": [
    { "type": "customer", "id": "676f0f6765bdaa7d7d760f88" }
  ],
  "source": {
    "channel": "desktop",
    "deliveredAs": "customer_initiated",
    "bodyHtml": "<p>Hello, I have a question about your product.</p>",
    "bodyMarkdown": "Hello, I have a question about your product.",
    "author": { "type": "customer", "id": "676f0f6765bdaa7d7d760f88" }
  },
  "createdAt": "2025-01-15T10:30:00.000Z",
  "updatedAt": "2025-01-15T10:30:00.000Z"
}

Version Availability

This endpoint is only available in API version 2026-01-01.nova and newer.

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
bodyMarkdown: string

The content of the initial message in markdown format. Images referenced by URL or as base64 data URIs will be automatically uploaded and stored.

minLength1
from: object { id, type } or object { id, type }

The author initiating the conversation. Use type “contact” for customer/lead or “admin” for outreach.

One of the following:
Contact object { id, type }

Conversation initiated by a contact

id: string

The Featurebase contact ID

type: "contact"

The type of author. Use “contact” for customer/lead initiated conversations.

Admin object { id, type }

Conversation initiated by an admin (outreach)

id: string

The Featurebase admin ID

type: "admin"

The type of author. Use “admin” for admin initiated outreach conversations.

channel: optional "desktop" or "email"

The channel for the conversation. Defaults to “desktop” (SDK/widget).

One of the following:
"desktop"
"email"
createdAt: optional string

The time the conversation was created as an ISO timestamp. If not provided, the current time will be used. This field is recommended for migrating past conversations from another source.

recipients: optional object { to, bcc, cc }

Recipients for admin-initiated outreach. Required when from.type is “admin”. Specify at least one recipient in the “to” field.

to: EmailRecipients { emails, ids }

Primary recipients (To field)

emails: optional array of string

Array of email addresses

ids: optional array of string

Array of Featurebase contact IDs

bcc: optional EmailRecipients { emails, ids }

Primary recipients (To field)

emails: optional array of string

Array of email addresses

ids: optional array of string

Array of Featurebase contact IDs

cc: optional EmailRecipients { emails, ids }

Primary recipients (To field)

emails: optional array of string

Array of email addresses

ids: optional array of string

Array of Featurebase contact IDs

subject: optional string

Subject line for the email. Required when channel is “email” and from.type is “admin”.

maxLength500
ReturnsExpand Collapse
Conversation object { id, adminAssigneeId, botConversationStateLastUpdatedAt, 26 more }
id: string

Unique conversation identifier

adminAssigneeId: string

ID of the assigned admin

botConversationStateLastUpdatedAt: string

ISO timestamp when bot state last changed

brandId: string

ID of the brand associated with this conversation

createdAt: string

ISO timestamp when conversation was created

hasAdminOverriddenLanguage: boolean

Whether an admin has manually overridden the language for this conversation. When true, automatic language detection is disabled.

isBlocked: boolean

Whether the user is blocked

lastActivityAt: string

ISO timestamp of last activity

object: "conversation"

Object type identifier

participants: array of ConversationParticipant { id, type }

Participants in this conversation

id: string

Participant ID

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

Type of participant

One of the following:
"customer"
"lead"
"admin"
"bot"
"guest"
"integration"
priority: boolean

Whether this conversation is marked as priority

prioritySetAt: string

ISO timestamp when priority was set

snoozedUntil: string

ISO timestamp until which conversation is snoozed

state: "open" or "closed" or "snoozed"

Current state of the conversation

One of the following:
"open"
"closed"
"snoozed"
tags: array of ConversationTag { id, name, type }

Current tags applied anywhere in this conversation

id: string

Unique tag identifier

name: string

Current tag name

type: "tag"

Object type identifier for a tag

teamAssigneeId: string

ID of the assigned team

updatedAt: string

ISO timestamp when conversation was last updated

userPreferredLanguage: string

User’s preferred language

waitingSince: string

ISO timestamp when conversation started waiting

awaitingCustomerReply: optional boolean

Whether we are awaiting a customer reply

botConversationState: optional "active" or "handed_off_to_human" or "resolved"

State of AI agent handling for this conversation

One of the following:
"active"
"handed_off_to_human"
"resolved"
conversationParts: optional array of ConversationPart

Array of conversation parts (messages). Only included when fetching a single conversation 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

csatDebug: optional object { requestId, status, changeLockWindowEndsAt, 2 more }

Minimal CSAT diagnostics for the current effective request.

requestId: string

Canonical CSAT request ID used for the latest debug snapshot

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

Lifecycle status of the request represented in the debug snapshot

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

ISO timestamp when rating edits stop being accepted

emailDelivery: optional CsatEmailDelivery { status, failedAt, failureReason, 2 more }
status: "pending" or "sent" or "failed"

Email delivery status for the CSAT request when applicable

One of the following:
"pending"
"sent"
"failed"
failedAt: optional string

ISO timestamp when the CSAT email failed

failureReason: optional string

Operational failure reason for the CSAT email delivery

messageId: optional string

Email message ID associated with delivery

sentAt: optional string

ISO timestamp when the CSAT email was sent

lateSubmitWindowEndsAt: optional string

ISO timestamp when first-time submissions stop being accepted

csatHistory: optional array of object { channel, isLatestEffective, lastUpdatedAt, 14 more }

Historical CSAT requests for this conversation, ordered newest first.

channel: "desktop" or "email"

Channel used for the CSAT request

One of the following:
"desktop"
"email"
isLatestEffective: boolean

Whether this row represents the currently effective CSAT request for the conversation

lastUpdatedAt: string

ISO timestamp when the request last changed

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"

Lifecycle status for this historical CSAT request

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

ISO timestamp when the request was canceled

changeLockWindowEndsAt: optional string

ISO timestamp when edits to an existing rating stop being accepted

emailDelivery: optional CsatEmailDelivery { status, failedAt, failureReason, 2 more }
status: "pending" or "sent" or "failed"

Email delivery status for the CSAT request when applicable

One of the following:
"pending"
"sent"
"failed"
failedAt: optional string

ISO timestamp when the CSAT email failed

failureReason: optional string

Operational failure reason for the CSAT email delivery

messageId: optional string

Email message ID associated with delivery

sentAt: optional string

ISO timestamp when the CSAT email was sent

expiredAt: optional string

ISO timestamp when the request expired

lateSubmitWindowEndsAt: optional string

ISO timestamp when first-time submissions stop being accepted

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

ratedAt: optional string

ISO timestamp when the request was rated

remark: optional string

Submitted remark when present

score: optional number

Submitted score when this request was rated

minimum1
maximum5
workflow: optional CsatWorkflowLink { workflowActionId, workflowId, workflowRunId, workflowStepId }
csatSummary: optional object { lastUpdatedAt, status, canceledAt, 10 more }

Derived CSAT summary for this conversation when a rating request or rating exists.

lastUpdatedAt: string

ISO timestamp when the summary last changed

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

Current summary status for CSAT on this conversation

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

ISO timestamp when the request was canceled

channel: optional "desktop" or "email"

Channel used for the latest CSAT request when known

One of the following:
"desktop"
"email"
expiredAt: optional string

ISO timestamp when the request expired

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

ratedAt: optional string

ISO timestamp when the customer submitted a rating

remark: optional string

Optional remark left with the rating

requestedAt: optional string

ISO timestamp when the latest CSAT request was created

requestId: optional string

Canonical CSAT request ID

requestSource: optional "workflow"

Source of the latest CSAT request when known

score: optional number

CSAT score from 1 to 5 when rated

minimum1
maximum5
workflow: optional CsatWorkflowLink { workflowActionId, workflowId, workflowRunId, workflowStepId }
disableCustomerReply: optional boolean

Whether customer replies are disabled

readReceipts: optional array of object { id, lastReadPartId, userType }

Read receipts indicating how far each participant has read in the conversation. Each receipt maps a user to their last-read conversation part. The tracked position reflects the system read state and may reference parts the user cannot directly view (e.g., a contact’s read position may point to an internal admin note). Use these receipts to render read indicators and typing awareness, not to infer content access.

id: string

The internal ID of the user

lastReadPartId: string

The ID of the last conversation part this user has read. Note: This reflects the system-tracked read position and may reference a part the user cannot directly access (e.g., internal notes for contacts). The read state is advanced to the latest part in the conversation regardless of part visibility.

userType: "admin" or "customer" or "lead"

Type of user who has read the conversation

One of the following:
"admin"
"customer"
"lead"
source: optional object { bodyHtml, bodyMarkdown, channel, 4 more }
bodyHtml: string

Body of the initial message as HTML with signed image URLs

bodyMarkdown: string

Body of the initial message as markdown

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

Channel through which the conversation was initiated

One of the following:
"unknown"
"desktop"
"android"
"ios"
"email"
author: optional ConversationParticipant { id, type }
id: string

Participant ID

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

Type of participant

One of the following:
"customer"
"lead"
"admin"
"bot"
"guest"
"integration"
deliveredAs: optional "customer_initiated" or "admin_initiated"

How the conversation was initiated

One of the following:
"customer_initiated"
"admin_initiated"
subject: optional string

Subject line for email conversations

url: optional string

URL where the conversation was initiated

title: optional string

Conversation title

Create a conversation

curl https://do.featurebase.app/v2/conversations \
    -H 'Content-Type: application/json' \
    -H "Authorization: Bearer $FEATUREBASE_API_KEY" \
    -d '{
          "bodyMarkdown": "Hello, I have a question about your product.\\n\\n![screenshot](https://example.com/image.png)",
          "from": {
            "id": "676f0f6765bdaa7d7d760f88",
            "type": "contact"
          },
          "channel": "desktop",
          "createdAt": "2025-01-15T10:30:00.000Z",
          "subject": "Following up on your inquiry"
        }'
{
  "id": "12345",
  "adminAssigneeId": "507f1f77bcf86cd799439011",
  "botConversationStateLastUpdatedAt": "2025-01-15T10:30:00.000Z",
  "brandId": "507f1f77bcf86cd799439011",
  "createdAt": "2025-01-15T10:30:00.000Z",
  "hasAdminOverriddenLanguage": false,
  "isBlocked": false,
  "lastActivityAt": "2025-01-15T12:30:00.000Z",
  "object": "conversation",
  "participants": [
    {
      "id": "676f0f6765bdaa7d7d760f88",
      "type": "customer"
    }
  ],
  "priority": false,
  "prioritySetAt": "2025-01-15T10:30:00.000Z",
  "snoozedUntil": "2025-01-16T09:00:00.000Z",
  "state": "open",
  "tags": [
    {
      "id": "67ec1234abcd5678ef901234",
      "name": "Churn",
      "type": "tag"
    }
  ],
  "teamAssigneeId": "507f1f77bcf86cd799439012",
  "updatedAt": "2025-01-15T12:30:00.000Z",
  "userPreferredLanguage": "en",
  "waitingSince": "2025-01-15T10:30:00.000Z",
  "awaitingCustomerReply": true,
  "botConversationState": "active",
  "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"
          }
        }
      ]
    }
  ],
  "csatDebug": {
    "requestId": "csat_req_123",
    "status": "pending",
    "changeLockWindowEndsAt": "2025-01-16T12:30:00.000Z",
    "emailDelivery": {
      "status": "failed",
      "failedAt": "2025-01-15T10:31:00.000Z",
      "failureReason": "smtp_bounce",
      "messageId": "msg_123",
      "sentAt": "2025-01-15T10:31:00.000Z"
    },
    "lateSubmitWindowEndsAt": "2025-01-16T10:30:00.000Z"
  },
  "csatHistory": [
    {
      "channel": "desktop",
      "isLatestEffective": true,
      "lastUpdatedAt": "2025-01-15T10:35:00.000Z",
      "requestedAt": "2025-01-15T10:30:00.000Z",
      "requestId": "csat_req_123",
      "requestSource": "workflow",
      "status": "pending",
      "canceledAt": "2025-01-15T10:32:00.000Z",
      "changeLockWindowEndsAt": "2025-01-16T12:30:00.000Z",
      "emailDelivery": {
        "status": "failed",
        "failedAt": "2025-01-15T10:31:00.000Z",
        "failureReason": "smtp_bounce",
        "messageId": "msg_123",
        "sentAt": "2025-01-15T10:31:00.000Z"
      },
      "expiredAt": "2025-01-16T10:30:00.000Z",
      "lateSubmitWindowEndsAt": "2025-01-16T10:30:00.000Z",
      "ratedAgent": {
        "type": "teammate",
        "id": "507f1f77bcf86cd799439011"
      },
      "ratedAt": "2025-01-15T10:35:00.000Z",
      "remark": "Thanks for the quick help.",
      "score": 4,
      "workflow": {
        "workflowActionId": "action_123",
        "workflowId": "507f1f77bcf86cd799439011",
        "workflowRunId": "run_123",
        "workflowStepId": "step_123"
      }
    }
  ],
  "csatSummary": {
    "lastUpdatedAt": "2025-01-15T10:35:00.000Z",
    "status": "pending",
    "canceledAt": "2025-01-15T10:35:00.000Z",
    "channel": "desktop",
    "expiredAt": "2025-01-15T10:35:00.000Z",
    "ratedAgent": {
      "type": "teammate",
      "id": "507f1f77bcf86cd799439011"
    },
    "ratedAt": "2025-01-15T10:35:00.000Z",
    "remark": "Very helpful support.",
    "requestedAt": "2025-01-15T10:30:00.000Z",
    "requestId": "csat_req_123",
    "requestSource": "workflow",
    "score": 5,
    "workflow": {
      "workflowActionId": "action_123",
      "workflowId": "507f1f77bcf86cd799439011",
      "workflowRunId": "run_123",
      "workflowStepId": "step_123"
    }
  },
  "disableCustomerReply": false,
  "readReceipts": [
    {
      "id": "507f1f77bcf86cd799439011",
      "lastReadPartId": "8",
      "userType": "admin"
    }
  ],
  "source": {
    "bodyHtml": "<p>Hi, I have a question about your enterprise plan...</p>",
    "bodyMarkdown": "Hi, I have a question about your enterprise plan...",
    "channel": "desktop",
    "author": {
      "id": "676f0f6765bdaa7d7d760f88",
      "type": "customer"
    },
    "deliveredAs": "customer_initiated",
    "subject": "Question about pricing",
    "url": "https://example.com/pricing"
  },
  "title": "Question about pricing"
}
Returns Examples
{
  "id": "12345",
  "adminAssigneeId": "507f1f77bcf86cd799439011",
  "botConversationStateLastUpdatedAt": "2025-01-15T10:30:00.000Z",
  "brandId": "507f1f77bcf86cd799439011",
  "createdAt": "2025-01-15T10:30:00.000Z",
  "hasAdminOverriddenLanguage": false,
  "isBlocked": false,
  "lastActivityAt": "2025-01-15T12:30:00.000Z",
  "object": "conversation",
  "participants": [
    {
      "id": "676f0f6765bdaa7d7d760f88",
      "type": "customer"
    }
  ],
  "priority": false,
  "prioritySetAt": "2025-01-15T10:30:00.000Z",
  "snoozedUntil": "2025-01-16T09:00:00.000Z",
  "state": "open",
  "tags": [
    {
      "id": "67ec1234abcd5678ef901234",
      "name": "Churn",
      "type": "tag"
    }
  ],
  "teamAssigneeId": "507f1f77bcf86cd799439012",
  "updatedAt": "2025-01-15T12:30:00.000Z",
  "userPreferredLanguage": "en",
  "waitingSince": "2025-01-15T10:30:00.000Z",
  "awaitingCustomerReply": true,
  "botConversationState": "active",
  "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"
          }
        }
      ]
    }
  ],
  "csatDebug": {
    "requestId": "csat_req_123",
    "status": "pending",
    "changeLockWindowEndsAt": "2025-01-16T12:30:00.000Z",
    "emailDelivery": {
      "status": "failed",
      "failedAt": "2025-01-15T10:31:00.000Z",
      "failureReason": "smtp_bounce",
      "messageId": "msg_123",
      "sentAt": "2025-01-15T10:31:00.000Z"
    },
    "lateSubmitWindowEndsAt": "2025-01-16T10:30:00.000Z"
  },
  "csatHistory": [
    {
      "channel": "desktop",
      "isLatestEffective": true,
      "lastUpdatedAt": "2025-01-15T10:35:00.000Z",
      "requestedAt": "2025-01-15T10:30:00.000Z",
      "requestId": "csat_req_123",
      "requestSource": "workflow",
      "status": "pending",
      "canceledAt": "2025-01-15T10:32:00.000Z",
      "changeLockWindowEndsAt": "2025-01-16T12:30:00.000Z",
      "emailDelivery": {
        "status": "failed",
        "failedAt": "2025-01-15T10:31:00.000Z",
        "failureReason": "smtp_bounce",
        "messageId": "msg_123",
        "sentAt": "2025-01-15T10:31:00.000Z"
      },
      "expiredAt": "2025-01-16T10:30:00.000Z",
      "lateSubmitWindowEndsAt": "2025-01-16T10:30:00.000Z",
      "ratedAgent": {
        "type": "teammate",
        "id": "507f1f77bcf86cd799439011"
      },
      "ratedAt": "2025-01-15T10:35:00.000Z",
      "remark": "Thanks for the quick help.",
      "score": 4,
      "workflow": {
        "workflowActionId": "action_123",
        "workflowId": "507f1f77bcf86cd799439011",
        "workflowRunId": "run_123",
        "workflowStepId": "step_123"
      }
    }
  ],
  "csatSummary": {
    "lastUpdatedAt": "2025-01-15T10:35:00.000Z",
    "status": "pending",
    "canceledAt": "2025-01-15T10:35:00.000Z",
    "channel": "desktop",
    "expiredAt": "2025-01-15T10:35:00.000Z",
    "ratedAgent": {
      "type": "teammate",
      "id": "507f1f77bcf86cd799439011"
    },
    "ratedAt": "2025-01-15T10:35:00.000Z",
    "remark": "Very helpful support.",
    "requestedAt": "2025-01-15T10:30:00.000Z",
    "requestId": "csat_req_123",
    "requestSource": "workflow",
    "score": 5,
    "workflow": {
      "workflowActionId": "action_123",
      "workflowId": "507f1f77bcf86cd799439011",
      "workflowRunId": "run_123",
      "workflowStepId": "step_123"
    }
  },
  "disableCustomerReply": false,
  "readReceipts": [
    {
      "id": "507f1f77bcf86cd799439011",
      "lastReadPartId": "8",
      "userType": "admin"
    }
  ],
  "source": {
    "bodyHtml": "<p>Hi, I have a question about your enterprise plan...</p>",
    "bodyMarkdown": "Hi, I have a question about your enterprise plan...",
    "channel": "desktop",
    "author": {
      "id": "676f0f6765bdaa7d7d760f88",
      "type": "customer"
    },
    "deliveredAs": "customer_initiated",
    "subject": "Question about pricing",
    "url": "https://example.com/pricing"
  },
  "title": "Question about pricing"
}