POST /api/v1/conversations
Requires the conversations:write permission.
Authentication
Use an agent API key and secret.
Request body
Conversation creation details
Required: Yes.
application/json
| Field | Type | Required | Description |
|---|---|---|---|
| subject | string | No | Conversation subject |
| content | string | Yes | Initial message content (Accepts HTML as well) |
| inbox_id | integer | Yes | ID of an enabled email inbox for the conversation |
| team_id | integer | No | Team ID to be assigned when conversation is created nullable: true |
| agent_id | integer | No | Agent ID to be assigned when conversation is created nullable: true |
| contact_email | string (email) | Yes | Contact's email address |
| first_name | string | Yes | Contact's first name |
| last_name | string | No | Contact's last name |
| external_user_id | string | No | External identifier for the contact in your own system example: "crm-9f3a21" |
| attachments | array of integer | No | Array of attachment IDs |
| attachments[] | integer | ||
| initiator | string (enum) | Yes | Who initiated the conversation. 'contact' means the first message is treated as an incoming message from the contact; 'agent' means the first message is an outgoing reply from the agent. Automation rules are only evaluated for contact-initiated conversations (incoming messages); agent-initiated conversations skip automation rule evaluation. enum: ["agent", "contact"] |
| custom_attributes | object | No | Custom attributes to set on the conversation. Keys that are not defined conversation custom attributes are ignored. example: {"order_id": "A-1024", "plan": "pro"} |
| reuse_contact | boolean | No | When true, a matching existing contact is used as-is. When false and the caller has the contacts:write permission, the matched contact's name and email are updated and its external ID is filled in. Callers without contacts:write always reuse the contact as-is. default: false |
Responses
200
Conversation created successfully
Content type: application/json.
| Field | Type | Required | Description |
|---|---|---|---|
| status | string | No | example: "success" |
| data | object | No | |
| data.id | integer | No | Unique conversation ID example: 51 |
| data.created_at | string (date-time) | No | |
| data.updated_at | string (date-time) | No | |
| data.uuid | string (uuid) | No | Unique UUID for the conversation example: "7d692b95-73dc-4f53-9343-6ed47a3db903" |
| data.contact_id | integer | No | |
| data.inbox_id | integer | No | |
| data.closed_at | string (date-time) | No | nullable: true |
| data.resolved_at | string (date-time) | No | nullable: true |
| data.reference_number | string | No | Human-readable reference number for the conversation example: "150" |
| data.priority | string | No | nullable: true |
| data.priority_id | integer | No | nullable: true |
| data.status | string | No | Current status name of the conversation, e.g. Open, Snoozed, Resolved, Closed nullable: true example: "Open" |
| data.status_category | string (enum) | No | enum: ["open", "waiting", "resolved"] nullable: true |
| data.status_id | integer | No | nullable: true |
| data.first_reply_at | string (date-time) | No | nullable: true |
| data.last_reply_at | string (date-time) | No | nullable: true |
| data.assigned_user_id | integer | No | nullable: true |
| data.assigned_team_id | integer | No | nullable: true |
| data.waiting_since | string (date-time) | No | nullable: true |
| data.snoozed_until | string (date-time) | No | nullable: true |
| data.subject | string | No | Subject line of the conversation nullable: true example: "[GitHub] A third-party GitHub Application has been added" |
| data.inbox_mail | string (email) | No | Email address of the inbox, empty for non-email inboxes example: "[email protected]" |
| data.inbox_reply_to | string | No | Reply-to address of the inbox |
| data.inbox_name | string | No | Name of the inbox example: "Support Inbox" |
| data.inbox_channel | string (enum) | No | Channel type of the inbox enum: ["email", "livechat"] example: "email" |
| data.tags | array of string | No | nullable: true |
| data.tags[] | string | ||
| data.meta | object | No | nullable: true |
| data.custom_attributes | object | No | nullable: true |
| data.last_message_at | string (date-time) | No | nullable: true |
| data.last_message | string | No | Content of the last message in the conversation nullable: true example: "Hey! A third-party GitHub Application was recently authorized..." |
| data.last_message_sender | string (enum) | No | Who sent the last message enum: ["contact", "agent"] nullable: true example: "contact" |
| data.last_interaction | string | No | Content of the last non-activity message nullable: true |
| data.last_interaction_at | string (date-time) | No | nullable: true |
| data.last_interaction_sender | string (enum) | No | enum: ["contact", "agent"] nullable: true |
| data.contact | object | No | |
| data.contact.id | integer | No | |
| data.contact.created_at | string (date-time) | No | |
| data.contact.updated_at | string (date-time) | No | |
| data.contact.first_name | string | No | |
| data.contact.last_name | string | No | |
| data.contact.email | string (email) | No | nullable: true |
| data.contact.type | string (enum) | No | enum: ["contact", "visitor"] |
| data.contact.availability_status | string | No | |
| data.contact.avatar_url | string | No | nullable: true |
| data.contact.phone_number | string | No | nullable: true |
| data.contact.phone_number_country_code | string | No | nullable: true |
| data.contact.country | string | No | ISO 3166-1 alpha-2 country code nullable: true |
| data.contact.custom_attributes | object | No | nullable: true |
| data.contact.enabled | boolean | No | |
| data.contact.last_active_at | string (date-time) | No | nullable: true |
| data.contact.last_login_at | string (date-time) | No | nullable: true |
| data.contact.external_user_id | string | No | External identifier for the contact in your own system nullable: true |
| data.sla_policy_id | integer | No | nullable: true |
| data.sla_policy_name | string | No | nullable: true |
| data.applied_sla_id | integer | No | nullable: true |
| data.next_sla_deadline_at | string (date-time) | No | nullable: true |
| data.first_response_deadline_at | string (date-time) | No | nullable: true |
| data.resolution_deadline_at | string (date-time) | No | nullable: true |
| data.next_response_deadline_at | string (date-time) | No | nullable: true |
| data.next_response_met_at | string (date-time) | No | nullable: true |
| data.csat_rating | integer | No | nullable: true |
| data.csat_feedback | string | No | nullable: true |
| data.csat_responded_at | string (date-time) | No | nullable: true |
| data.previous_conversations | array of object | No | nullable: true |
| data.previous_conversations[].id | integer | No | |
| data.previous_conversations[].created_at | string (date-time) | No | |
| data.previous_conversations[].updated_at | string (date-time) | No | |
| data.previous_conversations[].uuid | string | No | |
| data.previous_conversations[].contact | object | No | |
| data.previous_conversations[].contact.first_name | string | No | |
| data.previous_conversations[].contact.last_name | string | No | |
| data.previous_conversations[].contact.avatar_url | string | No | nullable: true |
| data.previous_conversations[].last_message | string | No | nullable: true |
| data.previous_conversations[].last_message_at | string (date-time) | No | nullable: true |
| data.previous_conversations[].subject | string | No |
400
Invalid request
Content type: application/json.
| Field | Type | Required | Description |
|---|---|---|---|
| status | string | No | example: "error" |
| message | string | No | Error message example: "Invalid request" |
| data | unspecified | No | Additional error data nullable: true |
| error_type | string (enum) | No | enum: ["GeneralException", "PermissionException", "InputException", "DataException", "NetworkException", "NotFoundException", "ConflictException", "UnauthorizedException", "RateLimitException"] |
401
Unauthorized
Content type: application/json.
| Field | Type | Required | Description |
|---|---|---|---|
| status | string | No | example: "error" |
| message | string | No | Error message example: "Invalid request" |
| data | unspecified | No | Additional error data nullable: true |
| error_type | string (enum) | No | enum: ["GeneralException", "PermissionException", "InputException", "DataException", "NetworkException", "NotFoundException", "ConflictException", "UnauthorizedException", "RateLimitException"] |
403
Forbidden
Content type: application/json.
| Field | Type | Required | Description |
|---|---|---|---|
| status | string | No | example: "error" |
| message | string | No | Error message example: "Invalid request" |
| data | unspecified | No | Additional error data nullable: true |
| error_type | string (enum) | No | enum: ["GeneralException", "PermissionException", "InputException", "DataException", "NetworkException", "NotFoundException", "ConflictException", "UnauthorizedException", "RateLimitException"] |
500
Internal server error
Content type: application/json.
| Field | Type | Required | Description |
|---|---|---|---|
| status | string | No | example: "error" |
| message | string | No | Error message example: "Invalid request" |
| data | unspecified | No | Additional error data nullable: true |
| error_type | string (enum) | No | enum: ["GeneralException", "PermissionException", "InputException", "DataException", "NetworkException", "NotFoundException", "ConflictException", "UnauthorizedException", "RateLimitException"] |
Specification
Download the complete OpenAPI specification.
OpenAPI definition for this endpoint
openapi: 3.0.0
info:
title: Libredesk API
description: >-
REST API documentation for Libredesk helpdesk system.
## Authentication
The Libredesk API supports two authentication methods:
### 1. Basic Authentication
Use your API key and secret with Basic authentication:
```
Authorization: Basic <base64_encoded_api_key:api_secret>
```
### 2. Token Authentication
Use your API key and secret with token authentication:
```
Authorization: token api_key:api_secret
```
To obtain API credentials, generate them from your agent profile in the
Libredesk dashboard.
version: 1.0.0
servers:
- url: http://localhost:8080
description: Local development server
security:
- basicAuth: []
- tokenAuth: []
paths:
/api/v1/conversations:
post:
tags:
- Conversations
summary: Create Conversation
description: Requires the `conversations:write` permission.
operationId: handleCreateConversation
requestBody:
description: Conversation creation details
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateConversationRequest'
responses:
'200':
description: Conversation created successfully
content:
application/json:
schema:
$ref: '#/components/schemas/ConversationResponse'
'400':
description: Invalid request
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'403':
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
description: Internal server error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
security:
- basicAuth: []
- tokenAuth: []
components:
schemas:
CreateConversationRequest:
type: object
required:
- content
- inbox_id
- contact_email
- first_name
- initiator
properties:
subject:
type: string
description: Conversation subject
content:
type: string
description: Initial message content (Accepts HTML as well)
inbox_id:
type: integer
description: ID of an enabled email inbox for the conversation
team_id:
type: integer
nullable: true
description: Team ID to be assigned when conversation is created
agent_id:
type: integer
nullable: true
description: Agent ID to be assigned when conversation is created
contact_email:
type: string
format: email
description: Contact's email address
first_name:
type: string
description: Contact's first name
last_name:
type: string
description: Contact's last name
external_user_id:
type: string
description: External identifier for the contact in your own system
example: crm-9f3a21
attachments:
type: array
items:
type: integer
description: Array of attachment IDs
initiator:
type: string
enum:
- agent
- contact
description: >-
Who initiated the conversation. 'contact' means the first message is
treated as an incoming message from the contact; 'agent' means the
first message is an outgoing reply from the agent. Automation rules
are only evaluated for contact-initiated conversations (incoming
messages); agent-initiated conversations skip automation rule
evaluation.
custom_attributes:
type: object
additionalProperties: true
description: >-
Custom attributes to set on the conversation. Keys that are not
defined conversation custom attributes are ignored.
example:
order_id: A-1024
plan: pro
reuse_contact:
type: boolean
default: false
description: >-
When true, a matching existing contact is used as-is. When false and
the caller has the `contacts:write` permission, the matched
contact's name and email are updated and its external ID is filled
in. Callers without `contacts:write` always reuse the contact as-is.
ConversationResponse:
type: object
properties:
status:
type: string
example: success
data:
$ref: '#/components/schemas/Conversation'
ErrorResponse:
type: object
description: Error response format
properties:
status:
type: string
example: error
message:
type: string
description: Error message
example: Invalid request
data:
nullable: true
description: Additional error data
error_type:
type: string
enum:
- GeneralException
- PermissionException
- InputException
- DataException
- NetworkException
- NotFoundException
- ConflictException
- UnauthorizedException
- RateLimitException
Conversation:
type: object
properties:
id:
type: integer
example: 51
description: Unique conversation ID
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
uuid:
type: string
format: uuid
example: 7d692b95-73dc-4f53-9343-6ed47a3db903
description: Unique UUID for the conversation
contact_id:
type: integer
inbox_id:
type: integer
closed_at:
type: string
format: date-time
nullable: true
resolved_at:
type: string
format: date-time
nullable: true
reference_number:
type: string
example: '150'
description: Human-readable reference number for the conversation
priority:
type: string
nullable: true
priority_id:
type: integer
nullable: true
status:
type: string
example: Open
description: >-
Current status name of the conversation, e.g. Open, Snoozed,
Resolved, Closed
nullable: true
status_category:
type: string
nullable: true
enum:
- open
- waiting
- resolved
status_id:
type: integer
nullable: true
first_reply_at:
type: string
format: date-time
nullable: true
last_reply_at:
type: string
format: date-time
nullable: true
assigned_user_id:
type: integer
nullable: true
assigned_team_id:
type: integer
nullable: true
waiting_since:
type: string
format: date-time
nullable: true
snoozed_until:
type: string
format: date-time
nullable: true
subject:
type: string
example: '[GitHub] A third-party GitHub Application has been added'
description: Subject line of the conversation
nullable: true
inbox_mail:
type: string
format: email
example: [email protected]
description: Email address of the inbox, empty for non-email inboxes
inbox_reply_to:
type: string
description: Reply-to address of the inbox
inbox_name:
type: string
example: Support Inbox
description: Name of the inbox
inbox_channel:
type: string
example: email
description: Channel type of the inbox
enum:
- email
- livechat
tags:
type: array
items:
type: string
nullable: true
meta:
type: object
nullable: true
custom_attributes:
type: object
nullable: true
last_message_at:
type: string
format: date-time
nullable: true
last_message:
type: string
example: Hey! A third-party GitHub Application was recently authorized...
description: Content of the last message in the conversation
nullable: true
last_message_sender:
type: string
enum:
- contact
- agent
example: contact
description: Who sent the last message
nullable: true
last_interaction:
type: string
nullable: true
description: Content of the last non-activity message
last_interaction_at:
type: string
format: date-time
nullable: true
last_interaction_sender:
type: string
nullable: true
enum:
- contact
- agent
contact:
$ref: '#/components/schemas/ConversationContact'
sla_policy_id:
type: integer
nullable: true
sla_policy_name:
type: string
nullable: true
applied_sla_id:
type: integer
nullable: true
next_sla_deadline_at:
type: string
format: date-time
nullable: true
first_response_deadline_at:
type: string
format: date-time
nullable: true
resolution_deadline_at:
type: string
format: date-time
nullable: true
next_response_deadline_at:
type: string
format: date-time
nullable: true
next_response_met_at:
type: string
format: date-time
nullable: true
csat_rating:
type: integer
nullable: true
csat_feedback:
type: string
nullable: true
csat_responded_at:
type: string
format: date-time
nullable: true
previous_conversations:
type: array
items:
type: object
properties:
id:
type: integer
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
uuid:
type: string
contact:
type: object
properties:
first_name:
type: string
last_name:
type: string
avatar_url:
type: string
nullable: true
last_message:
type: string
nullable: true
last_message_at:
type: string
format: date-time
nullable: true
subject:
type: string
nullable: true
ConversationContact:
type: object
properties:
id:
type: integer
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
first_name:
type: string
last_name:
type: string
email:
type: string
format: email
nullable: true
type:
type: string
enum:
- contact
- visitor
availability_status:
type: string
avatar_url:
type: string
nullable: true
phone_number:
type: string
nullable: true
phone_number_country_code:
type: string
nullable: true
country:
type: string
nullable: true
description: ISO 3166-1 alpha-2 country code
custom_attributes:
type: object
nullable: true
enabled:
type: boolean
last_active_at:
type: string
format: date-time
nullable: true
last_login_at:
type: string
format: date-time
nullable: true
external_user_id:
type: string
nullable: true
description: External identifier for the contact in your own system
securitySchemes:
basicAuth:
type: http
scheme: basic
description: >-
Basic authentication using base64 encoded API key and secret. Format:
`Authorization: Basic <base64(api_key:api_secret)>`
tokenAuth:
type: apiKey
name: Authorization
in: header
description: >-
Token authentication using API key and secret. Format: `Authorization:
token api_key:api_secret`
