Escolha a API que sua aplicação usa. Cada API tem seus próprios mecanismos de autenticação e criação de sessões, além de seu próprio contrato de eventos.
Escolha uma conexão de telefonia
Uma chamada telefônica pode chegar ao GPT-Live por um tronco SIP ou por uma aplicação que retransmite áudio. Escolha a opção adequada ao seu sistema de telefonia atual e ao ponto em que sua aplicação precisa processar o áudio.
| Conexão | Áudio e responsabilidades da aplicação |
|---|---|
| SIP direto | O provedor troca o áudio da chamada com a OpenAI. Sua aplicação cuida dos webhooks, da configuração da sessão, das decisões sobre a chamada e da lógica de negócios. |
| Ponte de áudio no servidor | Sua aplicação retransmite o áudio do provedor ou da sala para o GPT-Live via WebSocket. Ela gerencia as duas conexões, a conversão de eventos, a reprodução e o ciclo de vida da chamada. |
A conexão do provedor com sua aplicação e a conexão da sua aplicação com a OpenAI são separadas. Por exemplo, uma pessoa pode entrar em uma sala por SIP enquanto um agente nessa sala se conecta ao GPT-Live via WebSocket.
Você usa Twilio, Telnyx, LiveKit ou Daily/Pipecat? Consulte Integrações do GPT-Live com parceiros para ver guias específicos de cada provedor.
SIP direto
O SIP direto mantém o áudio da chamada no caminho de mídia entre o provedor e a OpenAI. A sinalização SIP usa TLS, e o GPT-Live exige SRTP para o áudio da chamada. Seu backend continua responsável pela decisão sobre a chamada recebida, pela configuração da sessão, pela autorização e pela lógica de negócios.
Use uma conexão de banda lateral quando seu backend precisar receber eventos da sessão ou enviar comandos. Ela se conecta à conversa existente enquanto o SIP transporta o áudio. Atribua um único manipulador a cada ação para que entregas duplicadas de webhooks ou eventos observados em várias conexões não executem ferramentas duas vezes.
Mantenha o roteamento SIP e a configuração do provedor junto à integração que os utiliza. Os eventos de webhook, os identificadores de chamada e os payloads de aceitação do Realtime pertencem à Realtime API; use o contrato do GPT-Live para uma sessão Live.
Gerencie o ciclo de vida da chamada
Confirme que o suporte a SIP do GPT-Live está habilitado para seu projeto e que o tronco SIP do provedor está roteado para esse projeto antes de usar este fluxo. Os payloads de webhook e de aceitação do Realtime na outra aba seguem um contrato de API diferente.
Receba a chamada de entrada
Configure o endpoint de webhook do seu projeto para live.transport.incoming. Verifique a assinatura do webhook e elimine entregas duplicadas antes de tomar uma decisão sobre a chamada. A confirmação de recebimento de uma entrega não aceita a chamada.
O webhook identifica uma chamada SIP com data.type: "sip" e fornece data.session_id. Use esse ID de sessão sem alterações em todas as ações de chamada do Live. Trate data.sip_headers como metadados não confiáveis de quem está ligando, não como autorização.
Integrações existentes ainda podem receber o evento obsoleto live.call.incoming, que não tem data.type. Durante a migração, trate os dois nomes e mantenha a assinatura antiga até que todas as entregas e novas tentativas legadas tenham sido processadas. A mesma chamada pendente também pode emitir um webhook do Realtime; atribua um único manipulador à decisão de aceitar ou rejeitar, em vez de aceitar pelas duas APIs.
Aceite ou rejeite a chamada
Aplique as regras de autorização e roteamento da sua aplicação. Para aceitar a chamada, envie uma requisição POST /v1/live/sessions/{session_id}/accept autenticada com um objeto session no nível superior:
{
"session": {
"type": "live",
"model": "gpt-live-1",
"instructions": "You are answering an inbound support call.",
"audio": { "output": { "voice": "marin" } },
"delegation": { "type": "client" }
}
}Use Authorization: Bearer $OPENAI_API_KEY a partir do seu backend confiável nas requisições de controle de chamadas. Escolha a voz e o modo de delegação ao aceitar a chamada. O SIP negocia o formato de áudio, então omita audio.format. O exemplo seleciona a delegação ao cliente; seu backend deve processar o trabalho delegado. Consulte Delegação e ferramentas para ver as configurações de cliente e de Responses.
Uma aceitação bem-sucedida retorna 200 OK com o corpo vazio após a inicialização da sessão. Trate os erros HTTP antes de considerar a chamada aceita.
Para rejeitar a chamada, envie POST /v1/live/sessions/{session_id}/reject com um status SIP, como { "status_code": 486 } para indicar ocupado. O status deve ser um número inteiro entre 300 e 699, inclusive. A primeira decisão de aceitar ou rejeitar prevalece; uma decisão concorrente posterior retorna decision_already_made.
Conecte seu backend
Após a aceitação, conecte um WebSocket de banda lateral em wss://api.openai.com/v1/live/sessions/{session_id}/attach. Use o ID da sessão aceita, a mesma autenticação do projeto e os mesmos cabeçalhos de conexão. Não envie session.start novamente.
O SIP transporta o áudio da chamada. Use a conexão de banda lateral para transcrições, delegação, ferramentas, comandos e áudio espelhado. Defina um único responsável por cada efeito colateral, mesmo que várias conexões observem um evento.
Observe os eventos do teclado telefônico
A conexão de banda lateral recebe transport.dtmf.received quando a pessoa que está ligando pressiona uma tecla e transport.dtmf.send após uma ferramenta hospedada enviar um tom com sucesso. O campo event do evento contém um dos valores 0–9, *, # ou A–D.
Essas são notificações para observadores, não comandos do cliente. Não envie transport.dtmf.send para solicitar um tom, nem presuma que o canal de dados do navegador receba eventos do teclado telefônico.
Transfira ou encerre a chamada
Para transferir a chamada, envie POST /v1/live/sessions/{session_id}/refer com { "target_uri": "sip:agent@example.com" } para indicar o destino. Para desligar, envie POST /v1/live/sessions/{session_id}/hangup sem corpo de requisição. Ambas retornam 200 OK com o corpo vazio em caso de sucesso.
Mantenha a conexão de banda lateral aberta para receber os eventos finais e os dados de uso antes de liberar os recursos da aplicação. Uma requisição de desligamento bem-sucedida ou uma desconexão inesperada não substitui session.closed. Consulte Uso e encerramento controlado para saber mais sobre a finalização e os motivos de encerramento.
Este fluxo aceita chamadas de entrada. Não há suporte à criação de chamadas SIP de saída por POST /v1/live/sessions; use a integração com parceiros correspondente para chamadas de saída gerenciadas pelo provedor.
Pontes de áudio no servidor
Use a conexão WebSocket do GPT-Live quando sua aplicação receber um fluxo de áudio de um provedor de telefonia ou de um framework de agentes. A aplicação autentica as duas conexões, converte seus envelopes de eventos e retransmite o áudio nas duas direções.
O GPT-Live oferece suporte a áudio bruto G.711 μ-law e A-law a 8 kHz via WebSocket. Quando o fluxo do provedor usa o mesmo codec, a mesma taxa de amostragem e o mesmo número de canais, sua aplicação pode encaminhar os bytes de áudio bruto sem convertê-los para PCM. Preserve a ordem do áudio e use o formato de mensagem exigido por cada conexão. A correspondência entre os formatos de áudio não torna os dois protocolos de eventos intercambiáveis.
A ponte também é responsável por todo áudio que coloca na fila de reprodução. Considere o armazenamento em buffer do provedor, as interrupções e o encerramento da chamada no projeto da sua aplicação. Consulte Gerenciamento de sessões para saber mais sobre o ciclo de vida da sessão Live e Migre para o GPT-Live para ver as mudanças na alternância de turnos e no controle de reprodução.
Mantenha o identificador da chamada ou da sala do provedor junto ao ID da sessão da OpenAI para poder rastrear uma conversa nos dois sistemas.
Próximos passos com o GPT-Live
- WebSockets: conecte um fluxo de áudio do servidor ao GPT-Live.
- Webhooks e controles do lado do servidor: gerencie uma sessão a partir do seu backend.
- Delegação e ferramentas: conecte a fala ao seu backend de raciocínio e ferramentas.
- Gerenciamento de sessões: gerencie transcrições, estado da sessão e encerramento.
SIP é um protocolo usado para fazer chamadas telefônicas pela internet. Com SIP e a Realtime API, você pode direcionar chamadas telefônicas de entrada para a API.
Visão geral
Se quiser conectar um número de telefone à Realtime API, use um provedor de troncos SIP (por exemplo, Twilio). Esse serviço converte sua chamada telefônica em tráfego IP. Depois de comprar um número de telefone do seu provedor de troncos SIP, siga as instruções abaixo.
Comece criando um webhook para chamadas de entrada em configurações > Projeto > Webhooks no platform.openai.com.
Em seguida, aponte seu tronco SIP para o endpoint SIP da OpenAI, usando o ID do projeto
para o qual você configurou o webhook, por exemplo, sip:$PROJECT_ID@sip.api.openai.com;transport=tls.
Para residência de dados na Europa, use sip:$PROJECT_ID@sip-eu.api.openai.com;transport=tls em vez disso.
Para encontrar seu $PROJECT_ID, acesse configurações > Projeto > Geral. Essa página exibirá o ID do projeto, que
terá o prefixo proj_.
Quando a OpenAI receber tráfego SIP associado ao seu projeto,
seu webhook será acionado. O evento disparado será do tipo
realtime.call.incoming,
como no exemplo abaixo:
POST https://my_website.com/webhook_endpoint
user-agent: OpenAI/1.0 (+https://platform.openai.com/docs/webhooks)
content-type: application/json
webhook-id: wh_685342e6c53c8190a1be43f081506c52 # unique id for idempotency
webhook-timestamp: 1750287078 # timestamp of delivery attempt
webhook-signature: v1,K5oZfzN95Z9UVu1EsfQmfVNQhnkZ2pj9o9NDN/H/pI4= # signature to verify authenticity from OpenAI
{
"object": "event",
"id": "evt_685343a1381c819085d44c354e1b330e",
"type": "realtime.call.incoming",
"created_at": 1750287018, // Unix timestamp
"data": {
"call_id": "some_unique_id",
"sip_headers": [
{ "name": "From", "value": "sip:+142555512112@sip.example.com" },
{ "name": "To", "value": "sip:+18005551212@sip.example.com" },
{ "name": "Call-ID", "value": "03782086-4ce9-44bf-8b0d-4e303d2cc590"}
]
}
}A partir desse webhook, você pode aceitar ou rejeitar a chamada usando o valor call_id do webhook.
Ao aceitar a chamada, você fornecerá a configuração necessária
(instruções, voz etc.) para a sessão da Realtime API.
Depois que a sessão for estabelecida, você poderá configurar um WebSocket e monitorá-la como de costume. As APIs para
aceitar, rejeitar, monitorar, transferir e desligar a chamada estão documentadas abaixo.
Aceite a chamada
Use o endpoint de aceitação de chamadas para
aprovar a chamada de entrada e configurar a sessão em tempo real que a atenderá.
Envie os mesmos parâmetros que você enviaria em uma requisição
create client secret,
ou seja, verifique se o modelo em tempo real, a voz, as ferramentas ou as instruções estão configurados antes de conectar a
chamada ao modelo.
curl -X POST "https://api.openai.com/v1/realtime/calls/$CALL_ID/accept" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "realtime",
"model": "gpt-realtime-2.1",
"instructions": "You are Alex, a friendly concierge for Example Corp."
}'O caminho da requisição deve incluir o call_id do webhook
realtime.call.incoming,
e toda requisição exige o cabeçalho Authorization mostrado acima. O
endpoint retorna 200 OK assim que o trecho SIP da chamada começa a tocar e a sessão em tempo real
está sendo estabelecida.
Rejeite a chamada
Use o endpoint de rejeição de chamadas para
recusar um convite quando não quiser atender à chamada recebida (por exemplo, de
um código de país não compatível). Forneça o parâmetro de caminho call_id
e, opcionalmente, um status_code SIP (por exemplo, 486 para indicar "ocupado") no corpo
JSON para controlar a resposta enviada à operadora.
curl -X POST "https://api.openai.com/v1/realtime/calls/$CALL_ID/reject" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"status_code": 486}'Se nenhum código de status for fornecido, a API usará 603 Decline por padrão. Uma
solicitação bem-sucedida retorna 200 OK depois que a OpenAI entrega a resposta
SIP.
Monitore os eventos da chamada
Depois de aceitar uma chamada, abra uma conexão WebSocket com a mesma sessão para
receber um fluxo de eventos e enviar comandos em tempo real. Ao se conectar a uma chamada existente
usando o parâmetro call_id, o argumento model não é usado (pois já foi configurado
pelo endpoint accept).
Solicitação WebSocket
GET wss://api.openai.com/v1/realtime?call_id={call_id}
Parâmetros de consulta
| Parâmetro | Tipo | Descrição |
|---|---|---|
call_id | string | Identificador do webhook realtime.call.incoming. |
Cabeçalhos
Authorization: Bearer YOUR_API_KEY
O WebSocket funciona exatamente como qualquer outra conexão com a Realtime API. Envie
response.create
e outros eventos do cliente para controlar a chamada e escute os eventos do servidor para
acompanhar o progresso. Consulte Webhooks e controles do lado do servidor
para obter mais informações.
import WebSocket from "ws";
const callId = "rtc_u1_9c6574da8b8a41a18da9308f4ad974ce";
const ws = new WebSocket(`wss://api.openai.com/v1/realtime?call_id=${callId}`, {
headers: {
Authorization: `Bearer ${process.env.OPENAI_API_KEY}`,
},
});
ws.on("open", () => {
ws.send(
JSON.stringify({
type: "response.create",
})
);
});Redirecione a chamada
Transfira uma chamada ativa usando o
endpoint de transferência de chamadas. Forneça o
call_id e o target_uri que deve ser inserido no cabeçalho SIP Refer-To
(por exemplo, tel:+14155550123 ou sip:agent@example.com).
curl -X POST "https://api.openai.com/v1/realtime/calls/$CALL_ID/refer" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"target_uri": "tel:+14155550123"}'A OpenAI retorna 200 OK assim que o REFER é encaminhado ao seu provedor SIP. O
sistema de destino cuida do restante do fluxo da chamada para quem ligou.
Encerre a chamada
Encerre a sessão com o endpoint de encerramento de chamadas quando seu aplicativo precisar desconectar quem ligou. Esse endpoint pode ser usado para encerrar sessões em tempo real tanto SIP quanto WebRTC.
curl -X POST "https://api.openai.com/v1/realtime/calls/$CALL_ID/hangup" \
-H "Authorization: Bearer $OPENAI_API_KEY"A API responde com 200 OK quando começa a encerrar a chamada.
Faixas de IP de sinalização e mídia SIP
As chamadas SIP da Realtime API usam caminhos de rede separados para sinalização e mídia. Para garantir o funcionamento correto, configure sua rede para permitir o tráfego de sinalização e mídia conforme descrito abaixo.
Sinalização SIP
sip.api.openai.com e sip-eu.api.openai.com são endpoints roteados por GeoIP. Sua rede deve permitir
tráfego TCP/TLS de saída para os endereços retornados pelo DNS na porta 5061.
Mídia SRTP
A API especifica um endereço IP de mídia e uma porta UDP separados no SDP negociado. Sua rede deve permitir tráfego SRTP bidirecional por UDP de e para os seguintes blocos CIDR:
13.79.45.80/2823.98.140.64/2840.67.149.176/2840.83.204.240/28
Exemplos de servidor
A seguir está um exemplo de manipulador de realtime.call.incoming. Ele aceita a chamada e registra em log todos os eventos
da Realtime API.
Para o exemplo em Ruby, defina as variáveis do ambiente OPENAI_API_KEY e OPENAI_WEBHOOK_SECRET
e instale as dependências necessárias com
gem install openai webrick async-websocket.
from flask import Flask, request, Response, jsonify, make_response
from openai import OpenAI, InvalidWebhookSignatureError
import asyncio
import json
import os
import requests
import time
import threading
import websockets
app = Flask(__name__)
client = OpenAI(webhook_secret=os.environ["OPENAI_WEBHOOK_SECRET"])
AUTH_HEADER = {"Authorization": "Bearer " + os.environ["OPENAI_API_KEY"]}
call_accept = {
"type": "realtime",
"instructions": "You are a support agent.",
"model": "gpt-realtime-2.1",
}
response_create = {
"type": "response.create",
"response": {
"instructions": ("Say to the user 'Thank you for calling, how can I help you'")
},
}
async def websocket_task(call_id):
try:
async with websockets.connect(
"wss://api.openai.com/v1/realtime?call_id=" + call_id,
additional_headers=AUTH_HEADER,
) as websocket:
await websocket.send(json.dumps(response_create))
while True:
response = await websocket.recv()
print(f"Received from WebSocket: {response}")
except Exception as e:
print(f"WebSocket error: {e}")
@app.route("/", methods=["POST"])
def webhook():
try:
event = client.webhooks.unwrap(request.data, request.headers)
if event.type == "realtime.call.incoming":
requests.post(
"https://api.openai.com/v1/realtime/calls/"
+ event.data.call_id
+ "/accept",
headers={**AUTH_HEADER, "Content-Type": "application/json"},
json=call_accept,
)
threading.Thread(
target=lambda: asyncio.run(websocket_task(event.data.call_id)),
daemon=True,
).start()
return Response(status=200)
except InvalidWebhookSignatureError as e:
print("Invalid signature", e)
return Response("Invalid signature", status=400)
if __name__ == "__main__":
app.run(port=8000)Próximos passos
Agora que você se conectou via SIP, use a navegação à esquerda ou acesse estas páginas para começar a criar seu aplicativo em tempo real.
- Guia de criação de prompts em tempo real
- Gerenciamento de conversas
- Webhooks e controles do lado do servidor
- Gerenciamento de custos
- Transcrição em tempo real