curl --request POST \
--url https://{your-subdomain}.neetochat.com/api/external/v2/conversations \
--header 'Accept: <accept>' \
--header 'Content-Type: application/json' \
--header 'X-Api-Key: <x-api-key>' \
--data '
{
"visitor_attributes": {
"email": "sam@example.com",
"name": "Sam Brown",
"phone_number": "+14155550123",
"user_identifier": "customer-1042",
"traits": {
"plan": "Pro"
}
},
"messages_attributes": [
{
"body": "Hi, I need help with a refund."
}
],
"title": "Refund for order #1042",
"status": "open",
"priority": "high",
"assignee_email": "oliver@example.com",
"group_name": "Billing",
"tags": [
"refund",
"priority-customer"
],
"ticket_fields": {
"Order number": "1042"
},
"origin_page_url": "https://example.com/pricing",
"origin_page_title": "Pricing"
}
'const options = {
method: 'POST',
headers: {
'X-Api-Key': '<x-api-key>',
Accept: '<accept>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
visitor_attributes: {
email: 'sam@example.com',
name: 'Sam Brown',
phone_number: '+14155550123',
user_identifier: 'customer-1042',
traits: {plan: 'Pro'}
},
messages_attributes: [{body: JSON.stringify('Hi, I need help with a refund.')}],
title: 'Refund for order #1042',
status: 'open',
priority: 'high',
assignee_email: 'oliver@example.com',
group_name: 'Billing',
tags: ['refund', 'priority-customer'],
ticket_fields: {'Order number': '1042'},
origin_page_url: 'https://example.com/pricing',
origin_page_title: 'Pricing'
})
};
fetch('https://{your-subdomain}.neetochat.com/api/external/v2/conversations', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://{your-subdomain}.neetochat.com/api/external/v2/conversations"
payload = {
"visitor_attributes": {
"email": "sam@example.com",
"name": "Sam Brown",
"phone_number": "+14155550123",
"user_identifier": "customer-1042",
"traits": { "plan": "Pro" }
},
"messages_attributes": [{ "body": "Hi, I need help with a refund." }],
"title": "Refund for order #1042",
"status": "open",
"priority": "high",
"assignee_email": "oliver@example.com",
"group_name": "Billing",
"tags": ["refund", "priority-customer"],
"ticket_fields": { "Order number": "1042" },
"origin_page_url": "https://example.com/pricing",
"origin_page_title": "Pricing"
}
headers = {
"X-Api-Key": "<x-api-key>",
"Accept": "<accept>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"conversation": {
"id": "de414e85-a1b5-4240-a465-7b32606980ce",
"status": "open",
"title": "Refund for order #1042",
"priority": "low",
"channel_name": "b945fd3cd2573017052901d6dbd0832f",
"origin_page_url": "https://example.com/pricing",
"origin_page_title": "Pricing",
"created_at": "2026-09-23T18:07:53.661Z",
"updated_at": "2026-10-05T16:26:58.143Z",
"agent": {
"id": "05665eee-4602-4317-8f7f-767b04274e5f",
"name": "Oliver Smith",
"email": "oliver@example.com"
},
"group": {
"id": null,
"name": null
},
"visitor": {
"id": "2c79a334-0bc8-44e4-9504-331f59d400ab",
"name": "Sam Brown",
"email": "sam@example.com",
"phone_number": null,
"user_identifier": null
}
}
}{
"error": "A conversation must include at least one message."
}Create conversation
Start a conversation on behalf of a contact.
The contact is matched by user_identifier, then by email, and a new contact is created when neither matches.
curl --request POST \
--url https://{your-subdomain}.neetochat.com/api/external/v2/conversations \
--header 'Accept: <accept>' \
--header 'Content-Type: application/json' \
--header 'X-Api-Key: <x-api-key>' \
--data '
{
"visitor_attributes": {
"email": "sam@example.com",
"name": "Sam Brown",
"phone_number": "+14155550123",
"user_identifier": "customer-1042",
"traits": {
"plan": "Pro"
}
},
"messages_attributes": [
{
"body": "Hi, I need help with a refund."
}
],
"title": "Refund for order #1042",
"status": "open",
"priority": "high",
"assignee_email": "oliver@example.com",
"group_name": "Billing",
"tags": [
"refund",
"priority-customer"
],
"ticket_fields": {
"Order number": "1042"
},
"origin_page_url": "https://example.com/pricing",
"origin_page_title": "Pricing"
}
'const options = {
method: 'POST',
headers: {
'X-Api-Key': '<x-api-key>',
Accept: '<accept>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
visitor_attributes: {
email: 'sam@example.com',
name: 'Sam Brown',
phone_number: '+14155550123',
user_identifier: 'customer-1042',
traits: {plan: 'Pro'}
},
messages_attributes: [{body: JSON.stringify('Hi, I need help with a refund.')}],
title: 'Refund for order #1042',
status: 'open',
priority: 'high',
assignee_email: 'oliver@example.com',
group_name: 'Billing',
tags: ['refund', 'priority-customer'],
ticket_fields: {'Order number': '1042'},
origin_page_url: 'https://example.com/pricing',
origin_page_title: 'Pricing'
})
};
fetch('https://{your-subdomain}.neetochat.com/api/external/v2/conversations', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://{your-subdomain}.neetochat.com/api/external/v2/conversations"
payload = {
"visitor_attributes": {
"email": "sam@example.com",
"name": "Sam Brown",
"phone_number": "+14155550123",
"user_identifier": "customer-1042",
"traits": { "plan": "Pro" }
},
"messages_attributes": [{ "body": "Hi, I need help with a refund." }],
"title": "Refund for order #1042",
"status": "open",
"priority": "high",
"assignee_email": "oliver@example.com",
"group_name": "Billing",
"tags": ["refund", "priority-customer"],
"ticket_fields": { "Order number": "1042" },
"origin_page_url": "https://example.com/pricing",
"origin_page_title": "Pricing"
}
headers = {
"X-Api-Key": "<x-api-key>",
"Accept": "<accept>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"conversation": {
"id": "de414e85-a1b5-4240-a465-7b32606980ce",
"status": "open",
"title": "Refund for order #1042",
"priority": "low",
"channel_name": "b945fd3cd2573017052901d6dbd0832f",
"origin_page_url": "https://example.com/pricing",
"origin_page_title": "Pricing",
"created_at": "2026-09-23T18:07:53.661Z",
"updated_at": "2026-10-05T16:26:58.143Z",
"agent": {
"id": "05665eee-4602-4317-8f7f-767b04274e5f",
"name": "Oliver Smith",
"email": "oliver@example.com"
},
"group": {
"id": null,
"name": null
},
"visitor": {
"id": "2c79a334-0bc8-44e4-9504-331f59d400ab",
"name": "Sam Brown",
"email": "sam@example.com",
"phone_number": null,
"user_identifier": null
}
}
}{
"error": "A conversation must include at least one message."
}{your-subdomain} with your workspace’s subdomain. Learn how to find your subdomain in Workspace subdomain.
Headers
Use the X-Api-Key header to provide your workspace API key. Refer to Authentication for more information.
Specifies the expected response format. Must be set to application/json for proper API communication.
application/json Body
Details of the contact starting the conversation.
Hide child attributes
Hide child attributes
"sam@example.com"
"Sam Brown"
"+14155550123"
Your own identifier for the contact.
"customer-1042"
Custom attributes to store on the contact.
{ "plan": "Pro" }
"Refund for order #1042"
Status of the conversation. It must be one of the statuses of your workspace.
"open"
low, medium, high, urgent "high"
Email of the team member to assign the conversation to. It is ignored when no team member has this email.
"oliver@example.com"
Name of the group to assign the conversation to. It is ignored when no group has this name.
"Billing"
Names of the tags to add to the conversation. Tags that don't exist yet are created.
["refund", "priority-customer"]
Ticket field values keyed by the field's name. Use the option label for dropdown fields, an array of labels for multi-select fields and true or false for checkbox fields.
{ "Order number": "1042" }
URL of the page the conversation was started from.
"https://example.com/pricing"
Title of the page the conversation was started from.
"Pricing"
Response
Created - Conversation created successfully
Hide child attributes
Hide child attributes
"de414e85-a1b5-4240-a465-7b32606980ce"
Name of the conversation's status. The default statuses are new, open, waiting_on_customer, on_hold, closed, spam and trash, and your workspace may also have custom statuses.
"open"
"Refund for order #1042"
low, medium, high, urgent "low"
Unique identifier of the conversation's chat channel.
"b945fd3cd2573017052901d6dbd0832f"
URL of the page the conversation was started from.
"https://example.com/pricing"
Title of the page the conversation was started from.
"Pricing"
"2026-09-23T18:07:53.661Z"
Time the conversation was last changed. A new message or note in the conversation also updates it.
"2026-10-05T16:26:58.143Z"
Team member assigned to the conversation. All fields are null when the conversation is unassigned.
Contact who started the conversation.
Hide child attributes
Hide child attributes
"2c79a334-0bc8-44e4-9504-331f59d400ab"
"Sam Brown"
"sam@example.com"
null
null