Docs · API nativa
Conversas
As conversas que os endpoints de chat nativo guardam. Você pode listá-las, ler as mensagens, exportá-las e apagá-las. Todos esses endpoints exigem a sua chave de API e se limitam às suas próprias conversas.
Convenções#
- As leituras bem-sucedidas vêm embrulhadas como
{"status": "success", "data": {…}}; as escritas também trazem umamessage, e as exclusões têmmessagee não têmdata. Os erros são{"status": "error", "message": "…"}. - As datas são ISO 8601 em UTC.
- Os ids são inteiros.
- O limite de requisições é 300 por minuto por conta, com uma exceção anotada na exclusão permanente. Veja limites e cotas.
Os objetos#
Uma conversa traz mais campos do que os abaixo, a maioria controle interno. Estes são os que valem a pena usar:
| Campo | Significado |
|---|---|
id | o id da conversa |
title | o título. Sai da primeira mensagem, a menos que você defina um |
session_id | a chave enviada a POST /api/v1/chat, ou null |
model_name, profile_name | o modelo que respondeu por último. Uma conversa pode mudar de modelo entre os turnos |
effort | o esforço de raciocínio salvo, ou null |
total_messages, total_tokens | contadores |
is_active | se ela é candidata à conversa que o app web tem aberta. As conversas feitas pelos endpoints de chat são false. Uma feita com POST /api/v1/conversations começa como true, e o app web pode abri-la |
folder_id | o projeto em que ela está. As conversas da API ficam num projeto chamado API |
last_message_at, created_at, updated_at | timestamps |
Uma mensagem tem id, conversation_id, role (user, assistant ou system), content, reasoning, prompt_tokens, completion_tokens, total_tokens, response_time_ms, model_name, created_at, e um objeto metadata com detalhes como o request_id, o effort e algum cost_usd. Não dependa de outras chaves dentro de metadata.
GET/api/v1/conversations#
Lista as suas conversas, a mais recente primeiro.
| Query | Padrão | Notas |
|---|---|---|
skip | 0 | quantas pular |
limit | 50 | de 1 a 200 |
active_only | false | só as conversas cujo is_active é true: a que o app web tem aberta, e qualquer uma feita com POST /api/v1/conversations |
{
"status": "success",
"data": {
"conversations": [
{
"id": 3,
"session_id": "support-ticket-1042",
"title": "Say hello",
"model_name": "claude-sonnet-4-6",
"profile_name": "claude-sonnet-4-6@anthropic",
"effort": null,
"total_messages": 4,
"total_tokens": 100,
"is_active": false,
"folder_id": 1,
"last_message_at": "2026-10-10T17:43:47.000000Z",
"created_at": "2026-10-10T17:43:40.000000Z",
"updated_at": "2026-10-10T17:43:47.000000Z"
}
],
"total": 1
}
}total é o número de conversas nesta página, não no geral. Não há cursor: para ler mais, acrescente skip. Você não pode filtrar por session_id; então, para achar a conversa de uma sessão, leia a lista e compare o campo, até 200 por vez.
POST/api/v1/conversations#
Cria uma conversa vazia sem chamar nenhum modelo. Todos os campos são opcionais: title, session_id (até 255 caracteres, embora POST /api/v1/chat recuse mais de 191 e só procure no projeto API, então uma conversa feita aqui não pode ser continuada por session_id a partir do stream do chat), model_name e profile_name. Responde 201.
A conversa começa com is_active igual a true, e não é colocada no projeto API, então POST /api/v1/chat não a encontra por session_id. Ela pode virar a conversa que a pessoa vê no app web: envie "is_active": false com PUT para evitar isso. Para continuá-la, use o id dela com POST /api/v1/agent/chat.
GET/api/v1/conversations/{id}#
Devolve {"status": "success", "data": {"conversation": {…}}}.
PUT/api/v1/conversations/{id}#
Altera uma conversa. Todos os campos são opcionais:
| Campo | Notas |
|---|---|
title | até 255 caracteres. Definir um para o título automático. Um título vazio é ignorado, então não dá para limpar o título |
effort | low, medium, high, xhigh ou max |
is_active | true ou false |
folder_id | um dos seus projetos de chat, ou null para tirá-la dele. Outro tipo de projeto é um 422 |
GET/api/v1/conversations/{id}/messages#
| Query | Padrão | Notas |
|---|---|---|
skip | 0 | quantas pular |
limit | 100 | de 1 a 500 |
{
"status": "success",
"data": {
"messages": [
{ "id": 5, "conversation_id": 3, "role": "user", "content": "hi", "prompt_tokens": 12, "created_at": "2026-10-10T17:43:47.000000Z" },
{ "id": 6, "conversation_id": 3, "role": "assistant", "content": "Hello from the model.", "prompt_tokens": 12, "completion_tokens": 7, "total_tokens": 19, "model_name": "claude-sonnet-4-6", "created_at": "2026-10-10T17:43:47.000000Z" }
],
"total": 2
}
}As mensagens vêm ordenadas por data de criação, a mais antiga primeiro. Duas mensagens criadas no mesmo segundo não têm ordem definida entre si. total é, de novo, o tamanho da página.
POST/api/v1/conversations/{id}/messages#
Guarda uma mensagem. Não chama nenhum modelo. O corpo tem um role obrigatório (user, assistant ou system) e um content obrigatório, em string, e opcionalmente model_name, contagens de tokens e um objeto metadata. Responde 201.
As mensagens guardadas passam a fazer parte do histórico que o próximo turno daquela conversa envia ao modelo, então esta é uma forma de plantar contexto numa conversa, inclusive uma mensagem system, antes de você chamar POST /api/v1/agent/chat com o id dela.
GET/api/v1/conversations/{id}/export#
Baixa uma conversa. format é md (o padrão), html ou jsonl; qualquer outro valor é um 422.
curl -s "$SHVIA_URL/api/v1/conversations/3/export?format=jsonl" \
-H "Authorization: Bearer $SHVIA_API_KEY"A resposta é o próprio arquivo, com um header Content-Disposition. Em jsonl a primeira linha descreve a conversa, e cada linha seguinte é uma mensagem: {"type":"conversation",…} e depois {"type":"message","id","role","content","model","created_at"}.
GET/api/v1/conversations/{id}/usage#
Os tokens e o custo de uma conversa. Veja uso e custo.
Exclusão#
DELETE/api/v1/conversations/{id}#
Uma exclusão lógica: a conversa some das listas e as mensagens são mantidas. Não existe endpoint para restaurá-la.
DELETE/api/v1/conversations/{id}/permanent#
Apaga a conversa e as mensagens dela de vez, inclusive uma que já tinha sido apagada de forma lógica. Os registros que medem o seu uso permanecem, com o vínculo à conversa removido. É um dos endpoints numerados de limites e cotas: o teto dele é 20 por minuto, no contador que eles dividem.
Erros#
| Status | Corpo | Quando |
|---|---|---|
| 401 | {"message": "Unauthenticated."} | a credencial não é válida |
| 404 | {"status": "error", "message": "…"} | a conversa não existe, foi apagada ou não é sua |
| 422 | {"status": "error", "message": "…"}, com errors para um campo que falhou na validação | o corpo falhou na validação, o formato de exportação é desconhecido, ou o projeto não é um projeto de chat seu |
Uma conversa que não é sua é um 404, como se não existisse. O corpo é {"status": "error", …} ou o simples {"message": "Not Found"}, dependendo do endpoint e de a conversa existir ou não, então decida pelo status. A conversa própria de um bot não pode ser apagada: isso é um 422 com codigo igual a chat_do_bot_nao_se_apaga.