curl --request GET \
--url https://api.devic.ai/v1/assistants/{identifier}/chats/{chatUid} \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.devic.ai/v1/assistants/{identifier}/chats/{chatUid}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.devic.ai/v1/assistants/{identifier}/chats/{chatUid}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.devic.ai/v1/assistants/{identifier}/chats/{chatUid}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.devic.ai/v1/assistants/{identifier}/chats/{chatUid}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.devic.ai/v1/assistants/{identifier}/chats/{chatUid}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.devic.ai/v1/assistants/{identifier}/chats/{chatUid}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"chatUID": "550e8400-e29b-41d4-a716-446655440000",
"clientUID": "f9a44905-3193-4bd2-a81a-71156aa7eb66",
"userUID": "7a735eda-69e7-420b-9507-6abf80ad2e34",
"name": "Solar panel recommendations",
"archived": true,
"assistantSpecializationIdentifier": "550e8400-e29b-41d4-a716-446655440000",
"chatContent": [
{
"uid": "75ecbcfc-a3be-43ba-8da6-b3e16e8d7280",
"chatUid": "550e8400-e29b-41d4-a716-446655440000",
"role": "user",
"content": {
"message": "I would recommend a 450 W monocrystalline panel.",
"data": {},
"files": [
{
"name": "invoice.pdf",
"donwloadUrl": "https://files.devic.ai/uploads/invoice.pdf",
"fileType": "DOCUMENT"
}
]
},
"timestamp": 1706000000000,
"userUID": "api-key:42",
"summary": "The user asks which panels to install on a 60 m2 roof.",
"contentSource": "finish_tool",
"tool_calls": [
{
"id": "call_abc123",
"type": "function",
"function": {
"name": "get_user_location",
"arguments": "{}"
}
}
],
"tool_call_id": "call_abc123",
"latencyMs": 1045,
"messageTokenUsage": {
"inputTokens": 123,
"outputTokens": 123,
"inputCachedTokens": 123,
"inputCacheWriteTokens": 123,
"outputCachedTokens": 123,
"reasoningOutputTokens": 123,
"totalTokens": 123,
"provider": "<string>",
"model": "<string>"
},
"messageCost": {
"inputCost": 123,
"outputCost": 123,
"inputCachedCost": 123,
"inputCacheWriteCost": 123,
"outputCachedCost": 123,
"reasoningOutputCost": 123,
"totalCost": 123,
"currency": "USD",
"calculatedAt": 123
}
}
],
"creationTimestampMs": 1789630543006,
"lastEditTimestampMs": 1789630572077,
"llm": "gpt-4.1",
"provider": "open-ai",
"contextWindow": 1050000,
"inputTokens": 6380,
"outputTokens": 372,
"tokenUsage": {
"model": "<string>",
"provider": "<string>",
"inputTokens": 123,
"outputTokens": 123,
"inputCachedTokens": 123,
"inputCacheWriteTokens": 123,
"outputCachedTokens": 123,
"reasoningOutputTokens": 123,
"totalCachedTokens": 123,
"cost": {
"inputCost": 123,
"outputCost": 123,
"inputCachedCost": 123,
"inputCacheWriteCost": 123,
"outputCachedCost": 123,
"reasoningOutputCost": 123,
"totalCost": 123
},
"secondaryCost": 123,
"secondaryInputTokens": 123,
"secondaryOutputTokens": 123,
"secondaryByOperation": {},
"pricingTimestamp": 123
},
"metadata": {},
"tenantId": "tenant_12345",
"tags": [
"support",
"onboarding"
],
"stopReason": "max_chat_messages_reached",
"triggerSource": {},
"guardrailResults": {},
"handedOff": true,
"handedOffSubThreadId": "64f5a5b8c123456789abcdef",
"pausedUntil": 123,
"pausedReason": "<string>",
"recalledMemories": [
{}
],
"coreMemories": [
{}
],
"compactions": [
{}
]
}Get chat history for a conversation
One conversation with all its messages, plus the model, tokens, cost and the memory or compaction events it went through. 404 when the conversation does not exist or belongs to another assistant.
curl --request GET \
--url https://api.devic.ai/v1/assistants/{identifier}/chats/{chatUid} \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.devic.ai/v1/assistants/{identifier}/chats/{chatUid}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.devic.ai/v1/assistants/{identifier}/chats/{chatUid}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.devic.ai/v1/assistants/{identifier}/chats/{chatUid}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.devic.ai/v1/assistants/{identifier}/chats/{chatUid}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.devic.ai/v1/assistants/{identifier}/chats/{chatUid}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.devic.ai/v1/assistants/{identifier}/chats/{chatUid}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"chatUID": "550e8400-e29b-41d4-a716-446655440000",
"clientUID": "f9a44905-3193-4bd2-a81a-71156aa7eb66",
"userUID": "7a735eda-69e7-420b-9507-6abf80ad2e34",
"name": "Solar panel recommendations",
"archived": true,
"assistantSpecializationIdentifier": "550e8400-e29b-41d4-a716-446655440000",
"chatContent": [
{
"uid": "75ecbcfc-a3be-43ba-8da6-b3e16e8d7280",
"chatUid": "550e8400-e29b-41d4-a716-446655440000",
"role": "user",
"content": {
"message": "I would recommend a 450 W monocrystalline panel.",
"data": {},
"files": [
{
"name": "invoice.pdf",
"donwloadUrl": "https://files.devic.ai/uploads/invoice.pdf",
"fileType": "DOCUMENT"
}
]
},
"timestamp": 1706000000000,
"userUID": "api-key:42",
"summary": "The user asks which panels to install on a 60 m2 roof.",
"contentSource": "finish_tool",
"tool_calls": [
{
"id": "call_abc123",
"type": "function",
"function": {
"name": "get_user_location",
"arguments": "{}"
}
}
],
"tool_call_id": "call_abc123",
"latencyMs": 1045,
"messageTokenUsage": {
"inputTokens": 123,
"outputTokens": 123,
"inputCachedTokens": 123,
"inputCacheWriteTokens": 123,
"outputCachedTokens": 123,
"reasoningOutputTokens": 123,
"totalTokens": 123,
"provider": "<string>",
"model": "<string>"
},
"messageCost": {
"inputCost": 123,
"outputCost": 123,
"inputCachedCost": 123,
"inputCacheWriteCost": 123,
"outputCachedCost": 123,
"reasoningOutputCost": 123,
"totalCost": 123,
"currency": "USD",
"calculatedAt": 123
}
}
],
"creationTimestampMs": 1789630543006,
"lastEditTimestampMs": 1789630572077,
"llm": "gpt-4.1",
"provider": "open-ai",
"contextWindow": 1050000,
"inputTokens": 6380,
"outputTokens": 372,
"tokenUsage": {
"model": "<string>",
"provider": "<string>",
"inputTokens": 123,
"outputTokens": 123,
"inputCachedTokens": 123,
"inputCacheWriteTokens": 123,
"outputCachedTokens": 123,
"reasoningOutputTokens": 123,
"totalCachedTokens": 123,
"cost": {
"inputCost": 123,
"outputCost": 123,
"inputCachedCost": 123,
"inputCacheWriteCost": 123,
"outputCachedCost": 123,
"reasoningOutputCost": 123,
"totalCost": 123
},
"secondaryCost": 123,
"secondaryInputTokens": 123,
"secondaryOutputTokens": 123,
"secondaryByOperation": {},
"pricingTimestamp": 123
},
"metadata": {},
"tenantId": "tenant_12345",
"tags": [
"support",
"onboarding"
],
"stopReason": "max_chat_messages_reached",
"triggerSource": {},
"guardrailResults": {},
"handedOff": true,
"handedOffSubThreadId": "64f5a5b8c123456789abcdef",
"pausedUntil": 123,
"pausedReason": "<string>",
"recalledMemories": [
{}
],
"coreMemories": [
{}
],
"compactions": [
{}
]
}Authorizations
An API key from your Devic console, sent as Authorization: Bearer <key>. An embedded front end sends a tenant-session token instead, so no API key reaches the browser, and an OAuth integration sends its access token. Missing, invalid or expired credentials get a 401. See Authentication.
Path Parameters
Identifier of the assistant that holds the conversation
Identifier of the conversation
Response
The conversation
A conversation with an assistant: its messages and everything the platform recorded about the run — model, tokens, cost, tags and the memory or compaction events it went through.
Unique identifier of the conversation. This is the chatUid you send to continue it.
"550e8400-e29b-41d4-a716-446655440000"
Account the conversation belongs to
"f9a44905-3193-4bd2-a81a-71156aa7eb66"
Identity that opened the conversation
"7a735eda-69e7-420b-9507-6abf80ad2e34"
Title of the conversation, when one was given or generated
"Solar panel recommendations"
Archived conversations stay readable but are kept out of the default listings
Assistant that holds the conversation
"550e8400-e29b-41d4-a716-446655440000"
The messages, oldest first. Omitted when the request asked for omitContent=true.
Show child attributes
Show child attributes
When the conversation was created, Unix milliseconds
1789630543006
When it last changed, Unix milliseconds
1789630572077
Model that answered
"gpt-4.1"
Provider of that model
"open-ai"
Context capacity of the model in tokens. Absent for models the platform does not know the capacity of.
1050000
Input tokens of the whole conversation
6380
Output tokens of the whole conversation
372
Full accounting of the conversation: the model's own tokens and cost, plus what the secondary calls (summarisation, compaction, evaluations) added, broken down by operation.
Show child attributes
Show child attributes
The metadata the conversation was opened with, including the canonical subtenantId
Tenant the conversation is attributed to, in multi-tenant setups
"tenant_12345"
Tags stored on the conversation
["support", "onboarding"]
Why the platform stopped the conversation, when it did (max_chat_messages_reached, error, ...)
"max_chat_messages_reached"
Set when an app-integration trigger opened the conversation instead of a person
What the guardrails decided on this conversation
The conversation is paused waiting for a subagent to finish
Thread of the subagent it is waiting on
"64f5a5b8c123456789abcdef"
When a self-paused assistant resumes, Unix milliseconds
Reason the assistant gave for pausing
Long-term-memory recalls of this conversation, each with the facts or entities it surfaced and the messageUid of the message that brought it in, so a client can interleave them with the messages. Only for assistants with memory enabled.
Snapshots of the core-memory block the conversation was given, recorded whenever its revision changed. The block itself is re-rendered into the prompt on every call and never persisted with it. Only for assistants with core memory enabled.
Compaction checkpoints. Each folds the messages before its boundary into a summary plus the identifiers, paths and urls kept verbatim; from then on the model receives the checkpoint instead of those messages, which stay in chatContent. Only the newest one is in force.