Diálogo da Transcrição
O endpoint GET /api/calls/{id}/transcriptions/dialogue retorna a conversa completa da chamada em ordem cronológica, com as falas de todos os participantes intercaladas em uma única linha do tempo — pronta para exibir como um diálogo, alimentar análises ou enviar para um modelo de IA.
Diferente da listagem de transcrições, que retorna a transcrição de cada participante separadamente, este endpoint consolida tudo no servidor: alinha as gravações individuais no tempo, ordena os trechos e agrupa falas consecutivas do mesmo participante em turnos.
Requisição
Cabeçalhos:
Parâmetros:
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
id |
string (path) | Sim | ID da chamada |
Exemplos
curl -X GET "https://api.videochamada.com.br/api/calls/{id}/transcriptions/dialogue" \
-H "Authorization: Bearer {API_TOKEN}"
import requests
response = requests.get(
"https://api.videochamada.com.br/api/calls/{id}/transcriptions/dialogue",
headers={"Authorization": "Bearer {API_TOKEN}"},
)
dialogue = response.json()
for turn in dialogue["turns"]:
minutes, seconds = divmod(turn["elapsedMs"] // 1000, 60)
print(f"[{minutes:02d}:{seconds:02d}] {turn['label']}: {turn['text']}")
const response = await fetch(
'https://api.videochamada.com.br/api/calls/{id}/transcriptions/dialogue',
{ headers: { Authorization: 'Bearer {API_TOKEN}' } },
);
const dialogue = await response.json();
for (const turn of dialogue.turns) {
const totalSeconds = Math.floor(turn.elapsedMs / 1000);
const mm = String(Math.floor(totalSeconds / 60)).padStart(2, '0');
const ss = String(totalSeconds % 60).padStart(2, '0');
console.log(`[${mm}:${ss}] ${turn.label}: ${turn.text}`);
}
Resposta
{
"callId": "c1a2b3c4-d5e6-7f89-0a1b-2c3d4e5f6a7b",
"startedAt": 1754906100000,
"participants": [
{
"sessionId": "session_abc123",
"username": "Maria Souza",
"label": "Maria Souza"
},
{
"sessionId": "session_def456",
"username": null,
"label": "Participante 1"
}
],
"turns": [
{
"sessionId": "session_abc123",
"label": "Maria Souza",
"startMs": 1754906100000,
"endMs": 1754906104200,
"elapsedMs": 0,
"text": "Olá, tudo bem? Podemos começar?"
},
{
"sessionId": "session_def456",
"label": "Participante 1",
"startMs": 1754906105100,
"endMs": 1754906108000,
"elapsedMs": 5100,
"text": "Tudo ótimo, pode sim."
}
],
"incomplete": false,
"unplacedSessions": []
}
Campos:
| Campo | Tipo | Descrição |
|---|---|---|
callId |
string | ID da chamada |
startedAt |
number | null | Instante do primeiro turno do diálogo (epoch em milissegundos). null quando ainda não há falas |
participants |
array | Participantes com fala no diálogo, em ordem de entrada |
participants[].sessionId |
string | Identificador da sessão do participante |
participants[].username |
string | null | Nome informado pelo participante, quando disponível |
participants[].label |
string | Rótulo pronto para exibição. Usa o nome do participante ou Participante N; nomes duplicados recebem sufixo numérico |
turns |
array | Turnos de fala, em ordem cronológica |
turns[].sessionId |
string | Sessão do participante que falou |
turns[].label |
string | Rótulo do participante (o mesmo de participants) |
turns[].startMs |
number | Início do turno (epoch em milissegundos) |
turns[].endMs |
number | Fim do turno (epoch em milissegundos) |
turns[].elapsedMs |
number | Tempo decorrido desde o início do diálogo, em milissegundos — útil para exibir [mm:ss] |
turns[].text |
string | Texto do turno. Falas consecutivas do mesmo participante com pausas curtas (até cerca de 8 segundos) são agrupadas em um único turno |
incomplete |
boolean | true quando alguma sessão transcrita não pôde ser posicionada na linha do tempo |
unplacedSessions |
array | Sessões com transcrição que ficaram fora do diálogo (veja abaixo) |
unplacedSessions[].sessionId |
string | Sessão não posicionada |
unplacedSessions[].username |
string | null | Nome do participante, quando disponível |
unplacedSessions[].segmentCount |
number | Quantidade de trechos transcritos daquela sessão |
Trate incomplete: true
Quando incomplete é true, os turnos em turns continuam corretos entre si, mas há participantes com transcrição que não puderam ser alinhados na linha do tempo — eles aparecem em unplacedSessions. Nesse caso, apresente as transcrições dessas sessões separadamente (busque-as na listagem de transcrições), em vez de ignorá-las.
A transcrição chega de forma assíncrona
A transcrição é gerada pelo nosso pipeline de processamento depois dos arquivos de gravação, que por sua vez são processados após o fim da chamada. Um diálogo vazio (turns: []) ou parcial logo após o término é normal — tente novamente alguns minutos depois. O diálogo só está completo quando todos os participantes esperados aparecem em participants.
Erros
| Status | Mensagem | Quando |
|---|---|---|
| 404 | Call not found |
A chamada não existe |
| 403 | Recording does not belong to this project |
A chamada pertence a outro projeto (API key incorreta) |
| 404 | Call does not have recording enabled |
A chamada não está com gravação habilitada |
Boas práticas
- Polling com paciência: consulte o endpoint alguns minutos após o fim da chamada e repita até o diálogo estabilizar (todos os participantes presentes e
incomplete: false). - Use
elapsedMspara exibição: para mostrar o diálogo como uma conversa ([02:15] Maria: ...), useelapsedMs— ele já é relativo ao início do diálogo. - Use
label, nãousername: o campolabeljá resolve participantes sem nome e nomes duplicados; é o campo certo para exibição. - Envio para IA: o formato
label + textem ordem cronológica é ideal para prompts de resumo, análise de sentimento ou extração de tópicos.