Send a message by external thread id
One-endpoint integration for simple widgets: identifies the conversation by **your** thread id, creating it automatically on first use (and again after a previous conversation under the same id ended). Otherwise identical to `POST /v1/conversations/{id}/messages` — same response shape, same `actions` contract. `customer` and `metadata` are applied only when the call creates the conversation.
Authorization
AuthorizationRequiredBearer <token>Send your API key in the Authorization header on every request:
Authorization: Bearer sk_live_.... Keys are created in the admin UI under
Settings → API Keys and are project-scoped.
In: header
Request Body
application/jsonRequiredexternal_conversation_idRequiredstring255contentRequiredstring8000markdownbooleanSet to false to receive the reply as plain text
(markdown/HTML stripped) — same behavior as on
POST /v1/conversations/{id}/messages.
truecustomerobjectmetadataobjectHeader Parameters
Idempotency-KeystringMake POST/PATCH requests safe to retry. Same key + same body within 24 hours replays the original response. See Idempotency.
255Response Body
The user message with the agent's reply attached.
TypeScript Definitions
Use the response body type in TypeScript.
idRequiredstringMessage identifier prefixed with msg_.
objectRequiredstring"message"roleRequiredstring"user" | "assistant"contentRequiredstringcreated_atRequiredstring"date-time"replyRequiredobjectconversationRequiredobjectValidation failed.
TypeScript Definitions
Use the response body type in TypeScript.
errorRequiredobjectResource conflict.
TypeScript Definitions
Use the response body type in TypeScript.
errorRequiredobjectRate limit exceeded. See Retry-After header.
TypeScript Definitions
Use the response body type in TypeScript.
errorRequiredobjectThe agent did not reply within the sync window; recover via the transcript.
TypeScript Definitions
Use the response body type in TypeScript.
errorRequiredobjectcurl -X POST "https://api.meetdolores.ai/v1/messages" \
-H "Idempotency-Key: string" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"external_conversation_id": "intercom-thread-829311",
"content": "Do you ship to Canada?"
}'const body = JSON.stringify({
"external_conversation_id": "intercom-thread-829311",
"content": "Do you ship to Canada?"
})
fetch("https://api.meetdolores.ai/v1/messages", {
headers: {
"Idempotency-Key": "string",
"Authorization": "Bearer <token>"
},
body
})package main
import (
"fmt"
"net/http"
"io/ioutil"
"strings"
)
func main() {
url := "https://api.meetdolores.ai/v1/messages"
body := strings.NewReader(`{
"external_conversation_id": "intercom-thread-829311",
"content": "Do you ship to Canada?"
}`)
req, _ := http.NewRequest("POST", url, body)
req.Header.Add("Idempotency-Key", "string")
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := ioutil.ReadAll(res.Body)
fmt.Println(res)
fmt.Println(string(body))
}import requests
url = "https://api.meetdolores.ai/v1/messages"
body = {
"external_conversation_id": "intercom-thread-829311",
"content": "Do you ship to Canada?"
}
response = requests.request("POST", url, json = body, headers = {
"Idempotency-Key": "string",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
})
print(response.text)require 'net/http'
require 'json'
require 'uri'
uri = URI('https://api.meetdolores.ai/v1/messages')
req = Net::HTTP::Post.new(uri, {
'Authorization' => "Bearer #{ENV['DOLORES_API_KEY']}",
'Content-Type' => 'application/json',
})
req.body = {
external_conversation_id: "intercom-thread-829311",
content: "Do you ship to Canada?"
}.to_json
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
puts res.body<?php
$ch = curl_init('https://api.meetdolores.ai/v1/messages');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('DOLORES_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'external_conversation_id' => 'intercom-thread-829311',
'content' => 'Do you ship to Canada?'
]),
]);
echo curl_exec($ch);{
"id": "msg_01J8ZKWA3P4QRSTVWXYZ012345",
"object": "message",
"role": "user",
"content": "string",
"created_at": "2019-08-24T14:15:22Z",
"reply": {
"id": "msg_01J8ZKWA3P4QRSTVWXYZ012345",
"object": "message",
"role": "user",
"content": "string",
"created_at": "2019-08-24T14:15:22Z",
"actions": [
{
"type": "handoff"
}
]
},
"conversation": {
"id": "conv_01J8ZKW2M4NBCDEFGHJKMNPQRS",
"object": "conversation",
"status": "active",
"external_id": "intercom-thread-829311",
"customer_id": "string",
"metadata": {},
"created_at": "2019-08-24T14:15:22Z",
"last_message_at": "2019-08-24T14:15:22Z",
"ended_at": "2019-08-24T14:15:22Z"
}
}{
"error": {
"type": "invalid_request_error",
"code": "phone_invalid_format",
"message": "Phone must be in E.164 format (e.g. +15551234567).",
"param": "phone",
"request_id": "req_01HXY7P3K9ABCDEFGHJKMNPQRS"
}
}{
"error": {
"type": "invalid_request_error",
"code": "phone_invalid_format",
"message": "string",
"param": "string",
"request_id": "string"
}
}{
"error": {
"type": "invalid_request_error",
"code": "phone_invalid_format",
"message": "string",
"param": "string",
"request_id": "string"
}
}{
"error": {
"type": "invalid_request_error",
"code": "phone_invalid_format",
"message": "string",
"param": "string",
"request_id": "string"
}
}End a conversation
Closes the conversation (e.g. the end-user closed your widget, or a human agent finished a handed-off thread). Idempotent — ending an already-ended conversation returns its current state. Ending frees the `external_id` for a future conversation on the same thread.
Events
Audit log of webhook events delivered (or attempted) to your endpoints.