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.
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
Path Parameters
idRequiredstringConversation ID (prefixed with conv_).
Response Body
The (now ended) conversation.
TypeScript Definitions
Use the response body type in TypeScript.
idRequiredstringConversation identifier prefixed with conv_.
objectRequiredstring"conversation"statusRequiredstringactive — the agent replies to posted messages.
handed_off — the agent invoked a human handoff; posted messages
return 409 conversation_handed_off until the conversation is ended.
ended — closed (explicitly, by the agent, or after 30 minutes idle).
"active" | "ended" | "handed_off"external_idstring | null | nullYour chat tool's own thread identifier (max 255 characters). Unique per project among live conversations; reusable after the previous conversation under it has ended.
customer_idstring | null | nullThe linked customer (cust_…), when the conversation was created with a customer block.
metadataobjectFree-form key/value bag supplied at creation, echoed back verbatim.
created_atRequiredstring"date-time"last_message_atstring | null | null"date-time"ended_atstring | null | null"date-time"Resource not found.
TypeScript Definitions
Use the response body type in TypeScript.
errorRequiredobjectcurl -X POST "https://api.meetdolores.ai/v1/conversations/string/end" \
-H "Authorization: Bearer <token>"fetch("https://api.meetdolores.ai/v1/conversations/string/end", {
headers: {
"Authorization": "Bearer <token>"
}
})package main
import (
"fmt"
"net/http"
"io/ioutil"
)
func main() {
url := "https://api.meetdolores.ai/v1/conversations/string/end"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
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/conversations/string/end"
response = requests.request("POST", url, headers = {
"Authorization": "Bearer <token>"
})
print(response.text)require 'net/http'
require 'json'
require 'uri'
uri = URI('https://api.meetdolores.ai/v1/conversations/id_01HXY.../end')
req = Net::HTTP::Post.new(uri, {
'Authorization' => "Bearer #{ENV['DOLORES_API_KEY']}",
})
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/conversations/id_01HXY.../end');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('DOLORES_API_KEY'),
],
]);
echo curl_exec($ch);{
"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": "string",
"param": "string",
"request_id": "string"
}
}List messages (transcript)
The conversation transcript, oldest first. Only `user` and `assistant` turns are returned.
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.