{"openapi":"3.1.0","info":{"title":"Voza API","version":"1.0.0","summary":"Mensagens e chamadas do WhatsApp, por QR code ou pela API oficial da Meta.","description":"Os corpos de mensagens, chamadas e webhooks seguem o formato da API oficial do WhatsApp (Meta). Guia completo: https://www.vozaapi.com/docs.","contact":{"url":"https://www.vozaapi.com/docs"}},"servers":[{"url":"https://www.vozaapi.com/v1"}],"security":[{"apiKey":[]}],"tags":[{"name":"Conta"},{"name":"Números"},{"name":"Webhooks"},{"name":"Mensagens"},{"name":"Mídias"},{"name":"Chamadas"},{"name":"Telefone web"},{"name":"Agentes de voz"}],"paths":{"/account":{"get":{"tags":["Conta"],"summary":"A conta da chave, com o plano e os limites","operationId":"getAccount","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"}}}},"401":{"description":"Chave ausente, inválida ou revogada (invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Conta bloqueada: trial_expired, subscription_inactive ou account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de requisições da conta (rate_limited), com Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/account/usage":{"get":{"tags":["Conta"],"summary":"O uso de um mês (UTC), no total e por número","operationId":"getUsage","parameters":[{"name":"month","in":"query","description":"AAAA-MM; o mês atual quando vazio.","schema":{"type":"string","pattern":"^\\d{4}-(0[1-9]|1[0-2])$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Usage"}}}},"422":{"description":"Mês num formato inválido.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Chave ausente, inválida ou revogada (invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Conta bloqueada: trial_expired, subscription_inactive ou account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de requisições da conta (rate_limited), com Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/account/ai-keys":{"get":{"tags":["Agentes de voz"],"summary":"Quais chaves de provedores de IA a conta guardou (nunca as chaves)","operationId":"getAiKeys","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiKeys"}}}},"401":{"description":"Chave ausente, inválida ou revogada (invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Conta bloqueada: trial_expired, subscription_inactive ou account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de requisições da conta (rate_limited), com Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"tags":["Agentes de voz"],"summary":"Guarda as chaves de provedores de IA da conta, encriptadas","operationId":"updateAiKeys","description":"Só com uma chave de API criada por um proprietário da conta. Só os provedores enviados mudam; null remove a chave. Cada chave nova é conferida no provedor: se ele a recusar (401), nenhuma chave do pedido fica guardada.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","minProperties":1,"additionalProperties":false,"properties":{"anthropic":{"type":["string","null"],"minLength":8,"maxLength":500},"deepgram":{"type":["string","null"],"minLength":8,"maxLength":500},"elevenlabs":{"type":["string","null"],"minLength":8,"maxLength":500},"cartesia":{"type":["string","null"],"minLength":8,"maxLength":500}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiKeys"}}}},"403":{"description":"Conta bloqueada, ou a chave de API não é de um proprietário (owner_only).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Dados inválidos (invalid_request), ou um provedor recusou a chave (invalid_provider_key; meta.providers diz quais).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Chave ausente, inválida ou revogada (invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de requisições da conta (rate_limited), com Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/tts":{"post":{"tags":["Agentes de voz"],"summary":"Uma frase falada por uma voz, em áudio","operationId":"textToSpeech","description":"Com a chave do provedor guardada na conta. O áudio fica guardado pela voz e pelo texto: a mesma frase volta sem esperar (X-Voza-Cache: hit).","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TtsRequest"}}}},"responses":{"200":{"description":"O áudio.","content":{"audio/mpeg":{"schema":{"type":"string","format":"binary"}},"audio/wav":{"schema":{"type":"string","format":"binary"}}}},"422":{"description":"Dados inválidos (invalid_request) ou a conta não tem a chave do provedor (missing_provider_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"O provedor de voz não gerou o áudio (tts_failed).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"O motor de agentes não respondeu (agents_unavailable) ou está no limite (agents_busy), com o motivo em meta.reason.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Chave ausente, inválida ou revogada (invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Conta bloqueada: trial_expired, subscription_inactive ou account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de requisições da conta (rate_limited), com Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/voices":{"get":{"tags":["Agentes de voz"],"summary":"As vozes da conta num provedor de voz","operationId":"listVoices","description":"Com a chave do provedor guardada na conta, então as vozes clonadas da conta vêm também. A lista fica guardada por uma hora, por conta e provedor.","parameters":[{"name":"provider","in":"query","required":true,"schema":{"type":"string","enum":["elevenlabs","cartesia"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"provider":{"type":"string","enum":["elevenlabs","cartesia"]},"data":{"type":"array","items":{"$ref":"#/components/schemas/Voice"}}}}}}},"422":{"description":"provider inválido (invalid_request) ou a conta não tem a chave do provedor (missing_provider_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"O provedor de voz não devolveu a lista (voices_failed).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"O motor de agentes não respondeu (agents_unavailable) ou está no limite (agents_busy), com o motivo em meta.reason.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Chave ausente, inválida ou revogada (invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Conta bloqueada: trial_expired, subscription_inactive ou account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de requisições da conta (rate_limited), com Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/agents/test-sessions":{"post":{"tags":["Agentes de voz"],"summary":"Uma chamada de teste com um agente, pelo navegador, sem WhatsApp","operationId":"createAgentTestSession","description":"Dê o token ao navegador, que envia a oferta SDP em POST /agents/test-sessions/connect. Com number_id, o motor assina com o segredo do agente do número, e os eventos (test: true) vão para onde vão os do agente do número; sem ele, a resposta traz um segredo só desta chamada, e os eventos não são enviados. A chamada de teste conta nas sessões de agente da conta (limits.agent_sessions e limits.agent_tests em GET /account) e termina depois de 10 minutos.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["agent_ref","callback_url"],"properties":{"agent_ref":{"type":"string","maxLength":255},"callback_url":{"type":"string","format":"uri","description":"https público."},"number_id":{"type":["string","null"]}}}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentTestSession"}}}},"404":{"description":"O número não existe nesta conta (not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"O número não tem um agente (agent_not_configured).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Dados inválidos (invalid_request).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"O motor de agentes não respondeu (agents_unavailable) ou está no limite (agents_busy), com o motivo em meta.reason.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Chave ausente, inválida ou revogada (invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Conta bloqueada: trial_expired, subscription_inactive ou account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de requisições da conta (rate_limited), com Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/agents/test-sessions/{session}":{"parameters":[{"name":"session","in":"path","required":true,"schema":{"type":"string"}}],"delete":{"tags":["Agentes de voz"],"summary":"Encerra a chamada de teste","operationId":"deleteAgentTestSession","responses":{"204":{"description":"Encerrada."},"404":{"description":"A chamada de teste não existe nesta conta (not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Chave ausente, inválida ou revogada (invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Conta bloqueada: trial_expired, subscription_inactive ou account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de requisições da conta (rate_limited), com Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/agents/test-sessions/connect":{"post":{"tags":["Agentes de voz"],"summary":"O navegador envia a oferta SDP da chamada de teste (uma vez, com o token)","operationId":"connectAgentTestSession","security":[{"agentToken":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SdpOffer"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"session":{"$ref":"#/components/schemas/SdpAnswer"}}}}}},"409":{"description":"O token já foi usado (token_used) ou o produto recusou a chamada (agent_unavailable).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Oferta inválida (invalid_request, invalid_offer) ou falta a chave de um provedor (missing_provider_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"A conta já tem todas as chamadas de teste (test_session_limit_reached) ou sessões de agente (agent_limit_reached) simultâneas que pode ter.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"O produto não enviou a configuração do agente (agent_config_unavailable).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"O motor de agentes não respondeu (agents_unavailable) ou está no limite (agents_busy), com o motivo em meta.reason.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Token ausente, inválido ou vencido (invalid_monitor_token, invalid_test_token).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Conta bloqueada: trial_expired, subscription_inactive ou account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/monitor/session":{"delete":{"tags":["Agentes de voz"],"summary":"O supervisor que entrou com este token sai da chamada","operationId":"leaveMonitorSession","description":"left é false quando o supervisor, ou a chamada, já não estava lá.","security":[{"agentToken":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"left":{"type":"boolean"}}}}}},"503":{"description":"O motor de agentes não respondeu (agents_unavailable) ou está no limite (agents_busy), com o motivo em meta.reason.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Token ausente, inválido ou vencido (invalid_monitor_token, invalid_test_token).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Conta bloqueada: trial_expired, subscription_inactive ou account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"O token já foi usado (token_used).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de requisições (rate_limited), com Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Agentes de voz"],"summary":"O navegador de um supervisor entra na chamada (uma vez, com o token)","operationId":"joinMonitorSession","security":[{"agentToken":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SdpOffer"},{"type":"object","properties":{"mode":{"type":"string","enum":["listen","takeover"],"default":"listen","description":"listen: ouve. takeover: já entra falando com quem ligou, no lugar da IA."}}}]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"monitor_id":{"type":"string","description":"O id deste supervisor, para takeover e release."},"call_id":{"type":"string"},"session":{"$ref":"#/components/schemas/SdpAnswer"}}}}}},"409":{"description":"O token já foi usado (token_used), a chamada não está com o agente (call_not_with_agent) ou já tem todos os supervisores (too_many_monitors).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Oferta inválida (invalid_request, invalid_offer).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"O motor de agentes não respondeu (agents_unavailable) ou está no limite (agents_busy), com o motivo em meta.reason.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Token ausente, inválido ou vencido (invalid_monitor_token, invalid_test_token).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Conta bloqueada: trial_expired, subscription_inactive ou account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de requisições (rate_limited), com Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/numbers":{"get":{"tags":["Números"],"summary":"Os números da conta","operationId":"listNumbers","parameters":[{"name":"external_ref","in":"query","description":"Só os números com esta referência sua.","schema":{"type":"string","maxLength":100}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Number"}}}}}}},"401":{"description":"Chave ausente, inválida ou revogada (invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Conta bloqueada: trial_expired, subscription_inactive ou account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de requisições da conta (rate_limited), com Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Números"],"summary":"Cria um número por QR code ou conecta um número oficial","operationId":"createNumber","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NumberCreate"}}}},"responses":{"201":{"description":"Criado. Um número por QR code começa em starting; um oficial, em connected. Com um webhook no pedido, a resposta traz também webhook, com o segredo.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NumberCreated"}}}},"403":{"description":"Conta bloqueada (trial_expired, subscription_inactive, account_suspended) ou no limite de números do plano (number_limit_reached).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Dados inválidos (invalid_request) ou a Meta recusou as credenciais (meta_refused).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"O motor ou a Meta não responderam (engine_unavailable, meta_unavailable).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Chave ausente, inválida ou revogada (invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de requisições da conta (rate_limited), com Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/numbers/{number}":{"parameters":[{"name":"number","in":"path","required":true,"description":"O id do número na Voza.","schema":{"type":"string"}}],"get":{"tags":["Números"],"summary":"O número, com o status lido na hora","operationId":"getNumber","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Number"}}}},"401":{"description":"Chave ausente, inválida ou revogada (invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Conta bloqueada: trial_expired, subscription_inactive ou account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de requisições da conta (rate_limited), com Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"O número não existe nesta conta (not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["Números"],"summary":"Muda o nome do número ou a sua referência (external_ref)","operationId":"updateNumber","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","minProperties":1,"properties":{"name":{"type":"string","maxLength":80},"external_ref":{"type":["string","null"],"maxLength":100,"description":"null remove a referência."}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Number"}}}},"422":{"description":"Dados inválidos (invalid_request).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Chave ausente, inválida ou revogada (invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Conta bloqueada: trial_expired, subscription_inactive ou account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de requisições da conta (rate_limited), com Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"O número não existe nesta conta (not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Números"],"summary":"Exclui o número (e desconecta o celular, num número por QR code)","operationId":"deleteNumber","responses":{"204":{"description":"Excluído."},"503":{"description":"O motor não respondeu; nada foi excluído.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Chave ausente, inválida ou revogada (invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Conta bloqueada: trial_expired, subscription_inactive ou account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de requisições da conta (rate_limited), com Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"O número não existe nesta conta (not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/numbers/{number}/qr":{"parameters":[{"name":"number","in":"path","required":true,"description":"O id do número na Voza.","schema":{"type":"string"}}],"get":{"tags":["Números"],"summary":"O QR code para ler agora (só números por QR code)","operationId":"getNumberQr","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Qr"}}}},"409":{"description":"Número oficial (not_a_qr_number).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"O motor não respondeu (engine_unavailable).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Chave ausente, inválida ou revogada (invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Conta bloqueada: trial_expired, subscription_inactive ou account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de requisições da conta (rate_limited), com Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"O número não existe nesta conta (not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/numbers/{number}/relink":{"parameters":[{"name":"number","in":"path","required":true,"description":"O id do número na Voza.","schema":{"type":"string"}}],"post":{"tags":["Números"],"summary":"QR code: troca de celular. Oficial: verifica de novo na Meta, sem mexer nas configurações de chamada","operationId":"relinkNumber","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Number"}}}},"422":{"description":"A Meta recusou (meta_refused).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"O motor ou a Meta não responderam (engine_unavailable, meta_unavailable).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Chave ausente, inválida ou revogada (invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Conta bloqueada: trial_expired, subscription_inactive ou account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de requisições da conta (rate_limited), com Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"O número não existe nesta conta (not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/numbers/{number}/meta":{"parameters":[{"name":"number","in":"path","required":true,"description":"O id do número na Voza.","schema":{"type":"string"}}],"put":{"tags":["Números"],"summary":"Novo token (e chave secreta) de um número oficial","operationId":"updateNumberMeta","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["access_token"],"properties":{"access_token":{"type":"string"},"app_secret":{"type":["string","null"],"description":"Só quando mudou."}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Number"}}}},"409":{"description":"Número por QR code (not_an_official_number).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A Meta recusou (meta_refused).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"A Meta não respondeu (meta_unavailable).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Chave ausente, inválida ou revogada (invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Conta bloqueada: trial_expired, subscription_inactive ou account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de requisições da conta (rate_limited), com Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"O número não existe nesta conta (not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/numbers/{number}/calling":{"parameters":[{"name":"number","in":"path","required":true,"description":"O id do número na Voza.","schema":{"type":"string"}}],"get":{"tags":["Chamadas"],"summary":"As configurações de chamada de um número oficial, lidas na Meta","operationId":"getCallingSettings","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"calling":{"$ref":"#/components/schemas/CallingSettings"}}}}}},"409":{"description":"Número por QR code (not_an_official_number) ou token da Meta recusado (meta_token_invalid).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A Meta recusou o pedido (whatsapp_refused), com o erro dela em meta.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"A Meta não respondeu (meta_unavailable).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Chave ausente, inválida ou revogada (invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Conta bloqueada: trial_expired, subscription_inactive ou account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de requisições da conta (rate_limited), com Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"O número não existe nesta conta (not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"tags":["Chamadas"],"summary":"Muda as configurações de chamada de um número oficial na Meta","operationId":"updateCallingSettings","description":"Como na Meta: só os campos enviados mudam. sip não é aceito.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["calling"],"properties":{"calling":{"$ref":"#/components/schemas/CallingSettings"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}}}}}},"409":{"description":"Número por QR code (not_an_official_number) ou token da Meta recusado (meta_token_invalid).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Configurações inválidas (invalid_request) ou recusadas pela Meta (whatsapp_refused, com o erro dela em meta).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"A Meta não respondeu (meta_unavailable).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Chave ausente, inválida ou revogada (invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Conta bloqueada: trial_expired, subscription_inactive ou account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de requisições da conta (rate_limited), com Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"O número não existe nesta conta (not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/numbers/{number}/call-permissions/{wa_id}":{"parameters":[{"name":"number","in":"path","required":true,"description":"O id do número na Voza.","schema":{"type":"string"}},{"name":"wa_id","in":"path","required":true,"description":"O número do contato, com o código do país.","schema":{"type":"string","pattern":"^\\+?\\d{5,20}$"}}],"get":{"tags":["Chamadas"],"summary":"Se o número pode ligar para o contato agora","operationId":"getCallPermission","description":"Números oficiais: a resposta da Meta (call_permissions). Números por QR code: sempre granted, porque não há permissão a pedir.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CallPermission"}}}},"409":{"description":"O token da Meta foi recusado (meta_token_invalid).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"wa_id inválido (invalid_request) ou a Meta recusou o pedido (whatsapp_refused, com o erro dela em meta).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"A Meta não respondeu (meta_unavailable).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Chave ausente, inválida ou revogada (invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Conta bloqueada: trial_expired, subscription_inactive ou account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de requisições da conta (rate_limited), com Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"O número não existe nesta conta (not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/numbers/{number}/webhook":{"parameters":[{"name":"number","in":"path","required":true,"description":"O id do número na Voza.","schema":{"type":"string"}}],"get":{"tags":["Webhooks"],"summary":"O webhook do número","operationId":"getWebhook","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Webhook"}}}},"401":{"description":"Chave ausente, inválida ou revogada (invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Conta bloqueada: trial_expired, subscription_inactive ou account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de requisições da conta (rate_limited), com Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"O número não existe nesta conta (not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"tags":["Webhooks"],"summary":"Define, troca o segredo ou remove o webhook","operationId":"updateWebhook","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":["string","null"],"format":"uri","description":"https público; null remove o webhook."},"rotate_secret":{"type":"boolean"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Webhook"}}}},"401":{"description":"Chave ausente, inválida ou revogada (invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Conta bloqueada: trial_expired, subscription_inactive ou account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de requisições da conta (rate_limited), com Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"O número não existe nesta conta (not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/numbers/{number}/templates":{"parameters":[{"name":"number","in":"path","required":true,"description":"O id do número na Voza.","schema":{"type":"string"}}],"get":{"tags":["Mensagens"],"summary":"Os modelos de mensagem de um número oficial, lidos na Meta, uma página por vez","operationId":"listTemplates","description":"A lista da Meta (message_templates) da conta do WhatsApp Business do número, como a Meta a dá. paging.next e paging.previous apontam para a Voza.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"after","in":"query","description":"O cursor da página seguinte (paging.cursors.after).","schema":{"type":"string"}},{"name":"before","in":"query","description":"O cursor da página anterior (paging.cursors.before).","schema":{"type":"string"}},{"name":"fields","in":"query","description":"Os campos da Meta de cada modelo, separados por vírgulas.","schema":{"type":"string","default":"id,name,language,category,status,components"}},{"name":"name","in":"query","description":"Filtros da Meta: name, status, category e language.","schema":{"type":"string"}},{"name":"status","in":"query","schema":{"type":"string","examples":["APPROVED"]}},{"name":"category","in":"query","schema":{"type":"string","examples":["UTILITY"]}},{"name":"language","in":"query","schema":{"type":"string","examples":["pt_BR"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateList"}}}},"409":{"description":"Número por QR code (not_an_official_number) ou token da Meta recusado (meta_token_invalid).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Parâmetros inválidos (invalid_request) ou recusados pela Meta (whatsapp_refused, com o erro dela em meta).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"A Meta não respondeu (meta_unavailable).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Chave ausente, inválida ou revogada (invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Conta bloqueada: trial_expired, subscription_inactive ou account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de requisições da conta (rate_limited), com Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"O número não existe nesta conta (not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/numbers/{number}/messages":{"parameters":[{"name":"number","in":"path","required":true,"description":"O id do número na Voza.","schema":{"type":"string"}}],"post":{"tags":["Mensagens"],"summary":"Envia uma mensagem, com o corpo da Meta","operationId":"sendMessage","parameters":[{"name":"Idempotency-Key","in":"header","description":"Repetir com a mesma chave devolve o primeiro envio em vez de enviar de novo. A Voza guarda a primeira resposta por 24 horas, nos dois tipos de número.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9_.:-]+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageRequest"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageResponse"}}}},"409":{"description":"Número desconectado (number_not_connected), token da Meta recusado (meta_token_invalid) ou outro envio com a mesma Idempotency-Key em andamento (send_in_progress).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Corpo inválido (invalid_request), tipo só de números oficiais (unsupported_type) ou recusado pela Meta (whatsapp_refused).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de requisições da conta, com Retry-After, ou de envios da Meta num número oficial (rate_limited).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"O WhatsApp não aceitou a mensagem (whatsapp_refused), num número por QR code.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Serviço indisponível (engine_unavailable, number_reconnecting, ou meta_unavailable: o envio não chegou à Meta).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"O envio demorou demais (send_timeout), ou a Meta não respondeu a tempo e a mensagem pode ter chegado a ela (meta_timeout): repita com a mesma Idempotency-Key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Chave ausente, inválida ou revogada (invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Conta bloqueada: trial_expired, subscription_inactive ou account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"O número não existe nesta conta (not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/numbers/{number}/media/{media}":{"parameters":[{"name":"number","in":"path","required":true,"description":"O id do número na Voza.","schema":{"type":"string"}},{"name":"media","in":"path","required":true,"schema":{"type":"string"}}],"get":{"tags":["Mídias"],"summary":"Os bytes de uma mídia recebida","operationId":"getMedia","responses":{"200":{"description":"O arquivo, com o seu Content-Type.","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"404":{"description":"O número não existe nesta conta, ou a mídia não existe ou venceu (not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"O arquivo era grande demais para ser guardado (media_too_large).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"O WhatsApp não entregou o arquivo (media_unavailable).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"O motor ou a Meta não responderam (engine_unavailable, meta_unavailable).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Chave ausente, inválida ou revogada (invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Conta bloqueada: trial_expired, subscription_inactive ou account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de requisições da conta (rate_limited), com Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/numbers/{number}/calls":{"parameters":[{"name":"number","in":"path","required":true,"description":"O id do número na Voza.","schema":{"type":"string"}}],"get":{"tags":["Chamadas"],"summary":"O registro de chamadas, das mais novas para as mais antigas","operationId":"listCalls","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Call"}}}}}}},"401":{"description":"Chave ausente, inválida ou revogada (invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Conta bloqueada: trial_expired, subscription_inactive ou account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de requisições da conta (rate_limited), com Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"O número não existe nesta conta (not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Chamadas"],"summary":"Uma ação de chamada, com o corpo da Meta","operationId":"callAction","parameters":[{"name":"Idempotency-Key","in":"header","description":"Repetir com a mesma chave devolve a primeira resposta em vez de repetir a ação (depois de um meta_timeout, por exemplo). A Voza guarda a primeira resposta por 24 horas.","schema":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9_.:-]+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CallAction"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CallActionResponse"}}}},"404":{"description":"O número não existe nesta conta (not_found), ou a chamada não existe ou já terminou (call_not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"number_not_connected, call_not_ready, meta_token_invalid ou outra ação com a mesma Idempotency-Key em andamento (action_in_progress).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"invalid_request, not_on_whatsapp ou call_failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"channel_limit_reached, lines_busy ou rate_limited.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"O WhatsApp não aceitou a ação, num número por QR code (call_failed).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"lines_starting, engine_unavailable ou meta_unavailable (a ação não chegou à Meta: pode repetir).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"O motor demorou demais para responder (call_timeout), ou a Meta não respondeu a tempo e a ação pode ter chegado a ela (meta_timeout): repita com a mesma Idempotency-Key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Chave ausente, inválida ou revogada (invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Conta bloqueada: trial_expired, subscription_inactive ou account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/numbers/{number}/agent":{"parameters":[{"name":"number","in":"path","required":true,"description":"O id do número na Voza.","schema":{"type":"string"}}],"get":{"tags":["Agentes de voz"],"summary":"O agente de voz do número, sem o segredo","operationId":"getNumberAgent","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"agent":{"$ref":"#/components/schemas/Agent"}}}}}},"401":{"description":"Chave ausente, inválida ou revogada (invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Conta bloqueada: trial_expired, subscription_inactive ou account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de requisições da conta (rate_limited), com Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"O número não existe nesta conta (not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"tags":["Agentes de voz"],"summary":"Define o agente de voz do número e quando ele atende","operationId":"updateNumberAgent","description":"A Voza não guarda prompt nem configuração: no começo de cada chamada, o motor pede a configuração do agente em callback_url. A primeira vez, a resposta traz agent.secret, que assina os pedidos do motor e os eventos enviados a events_url.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentSettings"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"agent":{"$ref":"#/components/schemas/Agent"}}}}}},"422":{"description":"Dados inválidos (invalid_request).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Os agentes de voz não estão disponíveis nesta instalação (agents_unavailable).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Chave ausente, inválida ou revogada (invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Conta bloqueada: trial_expired, subscription_inactive ou account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de requisições da conta (rate_limited), com Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"O número não existe nesta conta (not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Agentes de voz"],"summary":"Desliga o agente do número e esquece o segredo","operationId":"deleteNumberAgent","responses":{"204":{"description":"Desligado."},"401":{"description":"Chave ausente, inválida ou revogada (invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Conta bloqueada: trial_expired, subscription_inactive ou account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de requisições da conta (rate_limited), com Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"O número não existe nesta conta (not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/numbers/{number}/agent/secret":{"parameters":[{"name":"number","in":"path","required":true,"description":"O id do número na Voza.","schema":{"type":"string"}}],"post":{"tags":["Agentes de voz"],"summary":"Um novo segredo para o agente; o anterior para de valer na hora","operationId":"rotateNumberAgentSecret","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"agent":{"$ref":"#/components/schemas/Agent"}}}}}},"409":{"description":"O número não tem um agente (agent_not_configured).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Chave ausente, inválida ou revogada (invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Conta bloqueada: trial_expired, subscription_inactive ou account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de requisições da conta (rate_limited), com Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"O número não existe nesta conta (not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/numbers/{number}/calls/{call}/agent":{"parameters":[{"name":"number","in":"path","required":true,"description":"O id do número na Voza.","schema":{"type":"string"}},{"name":"call","in":"path","required":true,"description":"O id da chamada no WhatsApp (call_id) ou o id dela na Voza.","schema":{"type":"string"}}],"post":{"tags":["Agentes de voz"],"summary":"Entrega ao agente uma chamada recebida que ainda está tocando","operationId":"answerCallWithAgent","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"agent_ref":{"type":"string","maxLength":255,"description":"Outro agente do produto; o do número quando vazio."}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"call":{"$ref":"#/components/schemas/Call"}}}}}},"404":{"description":"O número ou a chamada não existem nesta conta (not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Alguém já atendeu (call_answered_elsewhere), a chamada não está tocando (call_not_ringing), o número não tem um agente (agent_not_configured) ou o produto recusou a chamada (agent_unavailable).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Dados inválidos (invalid_request) ou falta a chave de um provedor (missing_provider_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"A conta já tem todas as sessões de agente simultâneas que pode ter (agent_limit_reached).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"O produto não enviou a configuração do agente (agent_config_unavailable).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"O motor de agentes não respondeu (agents_unavailable) ou está no limite (agents_busy), com o motivo em meta.reason.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Chave ausente, inválida ou revogada (invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Conta bloqueada: trial_expired, subscription_inactive ou account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/numbers/{number}/calls/{call}/monitor":{"parameters":[{"name":"number","in":"path","required":true,"description":"O id do número na Voza.","schema":{"type":"string"}},{"name":"call","in":"path","required":true,"description":"O id da chamada no WhatsApp (call_id) ou o id dela na Voza.","schema":{"type":"string"}}],"post":{"tags":["Agentes de voz"],"summary":"Um token curto para um supervisor ouvir a chamada que o agente atendeu","operationId":"monitorCall","responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MonitorToken"}}}},"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}}}}}},"404":{"description":"O número ou a chamada não existem nesta conta (not_found), ou o motor não a tem mais (call_not_found, monitor_not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A chamada não está com o agente (call_not_with_agent), ainda está sendo atendida (call_not_ready) ou outro supervisor a assumiu (not_in_control).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Dados inválidos (invalid_request).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"O motor de agentes não respondeu (agents_unavailable) ou está no limite (agents_busy), com o motivo em meta.reason.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Chave ausente, inválida ou revogada (invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Conta bloqueada: trial_expired, subscription_inactive ou account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de requisições da conta (rate_limited), com Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/numbers/{number}/calls/{call}/monitor/{monitor}":{"parameters":[{"name":"number","in":"path","required":true,"description":"O id do número na Voza.","schema":{"type":"string"}},{"name":"call","in":"path","required":true,"description":"O id da chamada no WhatsApp (call_id) ou o id dela na Voza.","schema":{"type":"string"}},{"name":"monitor","in":"path","required":true,"schema":{"type":"string"}}],"delete":{"tags":["Agentes de voz"],"summary":"Tira um supervisor da chamada (a IA volta a falar se ele estava com ela)","operationId":"removeMonitor","description":"left é false quando o supervisor, ou a chamada, já não estava lá.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"left":{"type":"boolean"}}}}}},"404":{"description":"O número ou a chamada não existem nesta conta (not_found), ou o motor não a tem mais (call_not_found, monitor_not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A chamada não está com o agente (call_not_with_agent), ainda está sendo atendida (call_not_ready) ou outro supervisor a assumiu (not_in_control).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Dados inválidos (invalid_request).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"O motor de agentes não respondeu (agents_unavailable) ou está no limite (agents_busy), com o motivo em meta.reason.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Chave ausente, inválida ou revogada (invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Conta bloqueada: trial_expired, subscription_inactive ou account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de requisições da conta (rate_limited), com Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/numbers/{number}/calls/{call}/whisper":{"parameters":[{"name":"number","in":"path","required":true,"description":"O id do número na Voza.","schema":{"type":"string"}},{"name":"call","in":"path","required":true,"description":"O id da chamada no WhatsApp (call_id) ou o id dela na Voza.","schema":{"type":"string"}}],"post":{"tags":["Agentes de voz"],"summary":"Uma instrução para a IA, que quem ligou não ouve","operationId":"whisperToAgent","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["text"],"properties":{"text":{"type":"string","maxLength":2000},"monitor":{"type":"string","description":"O supervisor que a manda, para o evento call.supervision."}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}}}}}},"404":{"description":"O número ou a chamada não existem nesta conta (not_found), ou o motor não a tem mais (call_not_found, monitor_not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A chamada não está com o agente (call_not_with_agent), ainda está sendo atendida (call_not_ready) ou outro supervisor a assumiu (not_in_control).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Dados inválidos (invalid_request).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"O motor de agentes não respondeu (agents_unavailable) ou está no limite (agents_busy), com o motivo em meta.reason.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Chave ausente, inválida ou revogada (invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Conta bloqueada: trial_expired, subscription_inactive ou account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de requisições da conta (rate_limited), com Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/numbers/{number}/calls/{call}/takeover":{"parameters":[{"name":"number","in":"path","required":true,"description":"O id do número na Voza.","schema":{"type":"string"}},{"name":"call","in":"path","required":true,"description":"O id da chamada no WhatsApp (call_id) ou o id dela na Voza.","schema":{"type":"string"}}],"post":{"tags":["Agentes de voz"],"summary":"A IA para de falar e o microfone do supervisor vai para a chamada","operationId":"takeOverCall","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["monitor"],"properties":{"monitor":{"type":"string"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}}}}}},"404":{"description":"O número ou a chamada não existem nesta conta (not_found), ou o motor não a tem mais (call_not_found, monitor_not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A chamada não está com o agente (call_not_with_agent), ainda está sendo atendida (call_not_ready) ou outro supervisor a assumiu (not_in_control).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Dados inválidos (invalid_request).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"O motor de agentes não respondeu (agents_unavailable) ou está no limite (agents_busy), com o motivo em meta.reason.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Chave ausente, inválida ou revogada (invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Conta bloqueada: trial_expired, subscription_inactive ou account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de requisições da conta (rate_limited), com Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/numbers/{number}/calls/{call}/release":{"parameters":[{"name":"number","in":"path","required":true,"description":"O id do número na Voza.","schema":{"type":"string"}},{"name":"call","in":"path","required":true,"description":"O id da chamada no WhatsApp (call_id) ou o id dela na Voza.","schema":{"type":"string"}}],"post":{"tags":["Agentes de voz"],"summary":"Devolve a chamada à IA","operationId":"releaseCall","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"monitor":{"type":"string"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}}}}}},"404":{"description":"O número ou a chamada não existem nesta conta (not_found), ou o motor não a tem mais (call_not_found, monitor_not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A chamada não está com o agente (call_not_with_agent), ainda está sendo atendida (call_not_ready) ou outro supervisor a assumiu (not_in_control).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Dados inválidos (invalid_request).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"O motor de agentes não respondeu (agents_unavailable) ou está no limite (agents_busy), com o motivo em meta.reason.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Chave ausente, inválida ou revogada (invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Conta bloqueada: trial_expired, subscription_inactive ou account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de requisições da conta (rate_limited), com Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/numbers/{number}/webphone-tokens":{"parameters":[{"name":"number","in":"path","required":true,"description":"O id do número na Voza.","schema":{"type":"string"}}],"post":{"tags":["Telefone web"],"summary":"Um token curto para o SDK do telefone web","operationId":"createWebphoneToken","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"label":{"type":"string","maxLength":80},"minutes":{"type":"integer","minimum":5,"maximum":720,"default":480}}}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebphoneToken"}}}},"401":{"description":"Chave ausente, inválida ou revogada (invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Conta bloqueada: trial_expired, subscription_inactive ou account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de requisições da conta (rate_limited), com Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"O número não existe nesta conta (not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/webphone/session":{"get":{"tags":["Telefone web"],"summary":"O número e os servidores ICE do token (usado pelo SDK)","operationId":"webphoneSession","security":[{"webphoneToken":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebphoneSession"}}}},"401":{"description":"Token ausente, inválido ou vencido (invalid_webphone_token).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Conta bloqueada: trial_expired, subscription_inactive ou account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de requisições do token (rate_limited), com Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/webphone/events":{"get":{"tags":["Telefone web"],"summary":"Os eventos das chamadas, por Server-Sent Events (usado pelo SDK)","operationId":"webphoneEvents","security":[{"webphoneToken":[]}],"parameters":[{"name":"token","in":"query","schema":{"type":"string"},"description":"O token, para o EventSource, que não envia cabeçalhos."},{"name":"Last-Event-ID","in":"header","schema":{"type":"string"},"description":"O último evento recebido: o fluxo continua do seguinte. O EventSource o envia sozinho ao reconectar."},{"name":"after","in":"query","schema":{"type":"integer"},"description":"O mesmo que Last-Event-ID, para quem não pode enviar o cabeçalho."}],"responses":{"200":{"description":"Eventos calls e claimed; retome com Last-Event-ID.","content":{"text/event-stream":{"schema":{"type":"string"}}}},"401":{"description":"Token ausente, inválido ou vencido (invalid_webphone_token).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Conta bloqueada: trial_expired, subscription_inactive ou account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Limite de requisições do token (rate_limited), com Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/webphone/calls":{"post":{"tags":["Telefone web"],"summary":"Uma ação de chamada com o token do telefone web (usado pelo SDK)","operationId":"webphoneCallAction","security":[{"webphoneToken":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CallAction"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CallActionResponse"}}}},"404":{"description":"A chamada não existe ou já terminou (call_not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"number_not_connected, call_not_ready, call_answered_elsewhere ou meta_token_invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"invalid_request, not_on_whatsapp ou call_failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"channel_limit_reached, lines_busy ou rate_limited.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"O WhatsApp não aceitou a ação, num número por QR code (call_failed).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"lines_starting, engine_unavailable ou meta_unavailable (a ação não chegou à Meta: pode repetir).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"O motor demorou demais para responder (call_timeout), ou a Meta não respondeu a tempo e a ação pode ter chegado a ela (meta_timeout): repita com a mesma Idempotency-Key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Token ausente, inválido ou vencido (invalid_webphone_token).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Conta bloqueada: trial_expired, subscription_inactive ou account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"webhooks":{"messages":{"post":{"summary":"Mensagens recebidas e status de entrega (envelope da Meta, field: messages)","description":"Sem um 2xx, novas tentativas com esperas crescentes por 24 horas, ou pelo prazo combinado com a Voza para a conta (webhook_retry_hours em GET /account, até 7 dias).","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEnvelope"}}}},"responses":{"200":{"description":"Qualquer 2xx em até 10 segundos."}}}},"calls":{"post":{"summary":"Eventos de chamada (envelope da Meta, field: calls)","description":"Numa fila só deles: sem um 2xx, novas tentativas depois de 5, 15 e 30 segundos; os de uma chamada tocando (connect, RINGING) desistem em 2 minutos, e o fim de uma chamada segue depois com o prazo dos eventos de mensagem. Uma chamada recusada acima do limite de chamadas simultâneas chega como terminate, com status REJECTED e voza_reason: channel_limit; uma que o agente recusou, com voza_reason: agent_unavailable e o motivo em voza_detail.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEnvelope"}}}},"responses":{"200":{"description":"Qualquer 2xx em até 10 segundos."}}}},"call.agent":{"post":{"summary":"Eventos do agente de voz (object: voza): call.agent.started, call.agent.state, call.transcript, call.agent.tool_call, call.metrics, call.supervision, call.agent.error, call.agent.declined e call.agent.ended","description":"Numa fila só deles, para o events_url do agente (assinado com o segredo do agente) ou para o webhook do número: os de uma chamada saem em ordem, um depois do outro. Novas tentativas em segundos por até 2 minutos; call.agent.ended, call.agent.error e call.agent.declined, depois, pelo prazo dos eventos de mensagem. timestamp em segundos e timestamp_ms em milissegundos.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentEvent"}}}},"responses":{"200":{"description":"Qualquer 2xx em até 10 segundos."}}}},"number.status":{"post":{"summary":"Mudança de status do número (object: voza)","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NumberStatusEvent"}}}},"responses":{"200":{"description":"Qualquer 2xx em até 10 segundos."}}}}},"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"Chave de API vz_…, criada no painel. Só no seu servidor."},"webphoneToken":{"type":"http","scheme":"bearer","description":"Token wp_… de POST /numbers/{id}/webphone-tokens. Também aceito em ?token=."},"agentToken":{"type":"http","scheme":"bearer","description":"Token mon_… de POST /numbers/{id}/calls/{call}/monitor, ou agt_… de POST /agents/test-sessions. Vale uma vez."}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Estável: use-o para decidir o que fazer."},"message":{"type":"string","description":"Para pessoas; pode mudar."},"details":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}},"description":"Os erros de cada campo, em invalid_request."},"meta":{"$ref":"#/components/schemas/ErrorMeta"}}}}},"ErrorMeta":{"type":"object","description":"Só quando o erro veio da Meta (o erro da Graph API) ou do motor dos números por QR code (reason).","properties":{"code":{"type":"integer","description":"O código da Meta: 131047 (fora da janela de 24 horas), 190 (token inválido), 138006 (sem permissão para ligar)…"},"subcode":{"type":["integer","null"]},"type":{"type":["string","null"],"examples":["OAuthException"]},"details":{"type":["string","null"],"description":"A explicação da Meta (error_data.details)."},"fbtrace_id":{"type":["string","null"],"description":"Para o suporte da Meta."},"reason":{"type":"string","description":"Por que o motor recusou, num número por QR code, ou o motor de agentes.","enum":["unreachable","unknown_session","not_found","not_linked","not_ready","too_large","not_on_whatsapp","invalid_request","lines_busy","whatsapp_refused","restarting","lines_starting","not_connected","timeout","engine_error","agent_config_unavailable","missing_provider_key","invalid_offer","call_not_found","call_ended","call_conflict","call_not_ready","too_many_monitors","monitor_not_found","not_in_control","tts_failed","at_capacity","draining","not_configured","runtime_error"]}}},"Account":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"status":{"type":"string","enum":["trial","active","suspended","canceled"]},"trial_ends_at":{"type":["string","null"],"format":"date-time"},"partner":{"type":"boolean","description":"Conta parceira (outro produto, limites definidos pela Voza): as chamadas não são recusadas pelo limite de chamadas simultâneas da conta."},"plan":{"type":["string","null"],"enum":["start","pro","scale",null]},"subscription":{"type":["object","null"],"properties":{"status":{"type":"string","description":"O status da assinatura no Stripe: active, past_due, canceled…"},"currency":{"type":"string","enum":["brl","usd"]},"renews_at":{"type":["string","null"],"format":"date-time"},"ends_at":{"type":["string","null"],"format":"date-time"}}},"limits":{"type":"object","properties":{"numbers":{"type":"integer"},"channels":{"type":"integer","description":"Chamadas simultâneas."},"requests_per_minute":{"type":"integer","description":"Requisições por minuto na API, somando todas as chaves da conta."},"agent_sessions":{"type":"integer","description":"Sessões de agente de voz ao mesmo tempo: chamadas atendidas pelos agentes e chamadas de teste."},"agent_tests":{"type":"integer","description":"Quantas dessas podem ser chamadas de teste."}}},"webhook_retry_hours":{"type":"integer","description":"Por quantas horas um evento de mensagem que falhou é tentado de novo (24, ou o combinado com a Voza, até 168)."}}},"UsageTotals":{"type":"object","properties":{"messages_sent":{"type":"integer"},"messages_received":{"type":"integer"},"calls":{"type":"integer"},"call_seconds":{"type":"integer"},"agent_calls":{"type":"integer","description":"Chamadas que um agente de voz atendeu."},"agent_seconds":{"type":"integer","description":"Os segundos da IA nessas chamadas (sem o tempo em que um supervisor estava com a chamada)."}}},"Usage":{"type":"object","properties":{"month":{"type":"string","examples":["2026-10"]},"totals":{"$ref":"#/components/schemas/UsageTotals"},"numbers":{"type":"array","items":{"allOf":[{"$ref":"#/components/schemas/UsageTotals"},{"type":"object","properties":{"number_id":{"type":["string","null"],"description":"null para um número já excluído."},"name":{"type":["string","null"]}}}]}}}},"Number":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"external_ref":{"type":["string","null"],"description":"A sua referência para o número (até 100 caracteres), que volta em metadata.external_ref dos webhooks."},"type":{"type":"string","enum":["qr","meta"]},"status":{"type":"string","enum":["starting","qr","connected","failed"]},"status_reason":{"$ref":"#/components/schemas/StatusReason"},"phone":{"type":["string","null"],"description":"Os dígitos, com o código do país."},"qr_url":{"type":["string","null"],"description":"A página pública do QR code (só números por QR code)."},"webhook_url":{"type":["string","null"]},"agent_mode":{"type":"string","enum":["off","always","fallback"],"description":"Quando o agente de voz do número atende (veja GET /numbers/{id}/agent)."},"connected_at":{"type":["string","null"],"format":"date-time"},"created_at":{"type":"string","format":"date-time"},"meta":{"type":"object","description":"Só nos números oficiais.","properties":{"phone_number_id":{"type":"string"},"waba_id":{"type":"string"},"display_phone_number":{"type":["string","null"]},"verified_name":{"type":["string","null"]},"quality_rating":{"type":["string","null"],"enum":["GREEN","YELLOW","RED","UNKNOWN",null]},"calling":{"type":["string","null"],"enum":["enabled","disabled","unavailable",null]},"error":{"type":["string","null"],"description":"O que a Meta recusou na última verificação."}}}}},"NumberCreated":{"allOf":[{"$ref":"#/components/schemas/Number"},{"type":"object","properties":{"webhook":{"allOf":[{"$ref":"#/components/schemas/Webhook"}],"description":"Só quando o pedido trouxe um webhook: o endereço e o segredo que assina os eventos."}}}]},"NumberCreate":{"type":"object","required":["name"],"properties":{"name":{"type":"string","maxLength":80},"external_ref":{"type":["string","null"],"maxLength":100,"description":"A sua referência para o número, como o id do canal no seu sistema."},"type":{"type":"string","enum":["qr","meta"],"default":"qr"},"webhook":{"type":"object","properties":{"url":{"type":["string","null"],"format":"uri"}},"description":"O webhook do número (https público), definido antes de o número conectar; a resposta traz o segredo. {id} e {external_ref} no endereço são trocados pelo id do número e pela external_ref (codificada para URL; exige external_ref no pedido)."},"webhook_url":{"type":["string","null"],"format":"uri","description":"O mesmo que webhook.url, com os mesmos marcadores."},"meta":{"type":"object","description":"Obrigatório com type: meta.","required":["phone_number_id","waba_id","access_token","app_secret"],"properties":{"phone_number_id":{"type":"string","pattern":"^\\d{5,30}$"},"waba_id":{"type":"string","pattern":"^\\d{5,30}$"},"access_token":{"type":"string","description":"Token permanente de um usuário do sistema, com whatsapp_business_messaging e whatsapp_business_management."},"app_secret":{"type":"string","pattern":"^[A-Fa-f0-9]{32}$"}}},"calling":{"oneOf":[{"$ref":"#/components/schemas/CallingSettings"},{"type":"string","const":"keep"}],"description":"Só com type: meta. As chamadas são ativadas com estas configurações; o que faltar fica com o padrão da Voza (ENABLED, DEFAULT, ENABLED). keep registra o número sem mexer nas configurações de chamada dele na Meta."}}},"StatusReason":{"type":["string","null"],"enum":["logged_out","restarting","failed","meta_refused",null],"description":"Por que o número está neste status: logged_out (o celular desconectou o aparelho), restarting (o motor está reconectando o número), failed (o WhatsApp recusou o aparelho) ou meta_refused (a Meta recusou o token ou o número). Vazio quando não há o que explicar."},"CallingSettings":{"type":"object","description":"O objeto calling das configurações do número na Meta, sem sip.","properties":{"status":{"type":"string","enum":["ENABLED","DISABLED"]},"call_icon_visibility":{"type":"string","enum":["DEFAULT","DISABLE_ALL"],"description":"O botão de chamada na conversa."},"callback_permission_status":{"type":"string","enum":["ENABLED","DISABLED"],"description":"Pedir ao contato permissão para ligar de volta."},"call_hours":{"type":"object","description":"O horário de atendimento, como na Meta (status, timezone_id, weekly_operating_hours, holiday_schedule)."},"call_icons":{"type":"object","description":"Como na Meta (restrict_to_user_countries)."}}},"CallPermission":{"type":"object","properties":{"messaging_product":{"type":"string"},"permission":{"type":"object","properties":{"status":{"type":"string","enum":["granted","temporary","no_permission"],"description":"Num número por QR code, sempre granted."},"expiration_time":{"type":"integer","description":"Quando uma permissão temporária vence (Unix)."}}},"actions":{"type":"array","description":"Como na Meta: o que o número pode fazer agora (start_call, send_call_permission_request) e os limites.","items":{"type":"object"}}}},"TemplateList":{"type":"object","description":"A resposta da Meta, como ela a dá.","properties":{"data":{"type":"array","items":{"type":"object","description":"Um modelo, com os campos pedidos: id, name, language, category, status, components…"},"examples":[[{"id":"1234567890","name":"pedido_enviado","language":"pt_BR","category":"UTILITY","status":"APPROVED","components":[{"type":"BODY","text":"Seu pedido {{1}} saiu para entrega."}]}]]},"paging":{"type":"object","properties":{"cursors":{"type":"object","properties":{"before":{"type":"string"},"after":{"type":"string"}}},"next":{"type":"string","description":"A próxima página, na Voza; ausente na última."},"previous":{"type":"string","description":"A página anterior, na Voza; ausente na primeira."}}}}},"Qr":{"type":"object","properties":{"status":{"type":"string"},"qr":{"type":["string","null"],"description":"PNG em data URI; null depois de conectado."},"qr_url":{"type":"string"}}},"Webhook":{"type":"object","properties":{"url":{"type":["string","null"]},"secret":{"type":["string","null"]}}},"MessageRequest":{"type":"object","required":["to"],"description":"O corpo da Meta. Todos os números: text, image, video, audio, document. Só números oficiais: template, interactive, sticker, location, contacts, reaction e context.","properties":{"messaging_product":{"type":"string","const":"whatsapp"},"recipient_type":{"type":"string","const":"individual"},"to":{"type":"string","examples":["5511987654321"]},"type":{"type":"string","enum":["text","image","video","audio","document","template","interactive","sticker","location","contacts","reaction"],"default":"text"},"text":{"type":"object","properties":{"body":{"type":"string","maxLength":4096},"preview_url":{"type":"boolean"}}},"image":{"$ref":"#/components/schemas/MediaLink"},"video":{"$ref":"#/components/schemas/MediaLink"},"audio":{"$ref":"#/components/schemas/MediaLink"},"document":{"$ref":"#/components/schemas/MediaLink"},"template":{"type":"object","description":"Como na API da Meta (name, language, components)."},"interactive":{"type":"object","description":"Como na API da Meta (button, list, cta_url, call_permission_request…)."},"sticker":{"type":"object","description":"Como na API da Meta (id ou link)."},"location":{"type":"object","description":"Como na API da Meta (latitude, longitude, name, address)."},"contacts":{"type":"array","items":{"type":"object"},"description":"Como na API da Meta (name, phones…)."},"reaction":{"type":"object","description":"Como na API da Meta (message_id, emoji)."},"context":{"type":"object","properties":{"message_id":{"type":"string"}},"description":"Responder a uma mensagem."}}},"MediaLink":{"type":"object","required":["link"],"properties":{"link":{"type":"string","format":"uri","description":"https público."},"caption":{"type":"string","maxLength":1024},"filename":{"type":"string"},"mime_type":{"type":"string"},"voice":{"type":"boolean","description":"Áudio como nota de voz (OGG/Opus)."}}},"MessageResponse":{"type":"object","properties":{"messaging_product":{"type":"string"},"contacts":{"type":"array","items":{"type":"object","properties":{"input":{"type":"string"},"wa_id":{"type":"string"}}}},"messages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"}}}}}},"CallAction":{"type":"object","required":["action"],"properties":{"messaging_product":{"type":"string","const":"whatsapp"},"action":{"type":"string","enum":["connect","pre_accept","accept","reject","terminate"]},"to":{"type":"string","description":"Em connect."},"call_id":{"type":"string","description":"Nas outras ações."},"session":{"type":"object","properties":{"sdp_type":{"type":"string","enum":["offer","answer"]},"sdp":{"type":"string"}}},"biz_opaque_callback_data":{"type":"string","maxLength":512}}},"CallActionResponse":{"type":"object","properties":{"messaging_product":{"type":"string"},"calls":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"}}},"description":"Em connect."},"success":{"type":"boolean"}}},"Call":{"type":"object","properties":{"id":{"type":"integer"},"call_id":{"type":"string"},"direction":{"type":"string","enum":["incoming","outgoing"]},"contact":{"type":"string"},"contact_name":{"type":["string","null"]},"status":{"type":"string","enum":["dialing","ringing","active","completed","missed","rejected","no_answer","failed"]},"end_reason":{"type":["string","null"],"description":"channel_limit (recusada acima do limite de chamadas simultâneas), agent_unavailable (o agente não pôde atender, ou o produto recusou a chamada, em always) ou lost (sem fim depois de 6 horas); null nas outras."},"end_detail":{"type":["string","null"],"description":"Com agent_unavailable, por que o agente recusou: product_refused, config_unavailable, missing_provider_key, invalid_offer, at_capacity, draining, account_limit, runtime_unavailable, runtime_error, whatsapp_refused ou error."},"started_at":{"type":"string","format":"date-time"},"answered_at":{"type":["string","null"],"format":"date-time"},"ended_at":{"type":["string","null"],"format":"date-time"},"duration":{"type":["integer","null"],"description":"Segundos."},"answered_by":{"type":["string","null"],"enum":["webphone","agent","api",null],"description":"Quem atendeu (numa chamada feita, quem ligou): um telefone web, o agente de voz ou o seu sistema com a chave de API. O primeiro fica com a chamada."},"agent":{"type":["object","null"],"description":"Só numa chamada que o agente atendeu.","properties":{"agent_ref":{"type":"string"},"session_id":{"type":["string","null"]},"seconds":{"type":["integer","null"],"description":"Os segundos da IA (sem o tempo de um supervisor), quando o agente terminou."}}}}},"AgentSettings":{"type":"object","required":["mode","agent_ref","callback_url"],"properties":{"require_fresh_config":{"type":"boolean","default":false,"description":"Exigir uma configuração nova do produto em cada chamada; nunca usar o cache quando o callback falhar."},"mode":{"type":"string","enum":["off","always","fallback"],"description":"off: só quando o produto entrega a chamada; always: toda chamada recebida; fallback: os telefones web tocam primeiro e o agente atende se ninguém atender."},"fallback_after_seconds":{"type":["integer","null"],"minimum":5,"maximum":120,"default":15},"agent_ref":{"type":"string","maxLength":255,"description":"O agente no seu produto."},"callback_url":{"type":"string","format":"uri","description":"Onde o motor pede a configuração (agent.config) e chama as ferramentas (tool.call). https público."},"events_url":{"type":["string","null"],"format":"uri","description":"Para os eventos do agente; sem ela, o webhook do número."}}},"Agent":{"allOf":[{"$ref":"#/components/schemas/AgentSettings"},{"type":"object","properties":{"secret":{"type":"string","description":"Só na criação e em POST /numbers/{id}/agent/secret: assina os pedidos do motor (X-Voza-Signature, o HMAC-SHA256 de \"{X-Voza-Timestamp}.{corpo}\"; recuse um timestamp a mais de 5 minutos do seu relógio) e os eventos enviados a events_url."}}}]},"AiKeys":{"type":"object","description":"Quais provedores têm uma chave guardada.","properties":{"anthropic":{"type":"boolean"},"deepgram":{"type":"boolean"},"elevenlabs":{"type":"boolean"},"cartesia":{"type":"boolean"}}},"Voice":{"type":"object","properties":{"id":{"type":"string","description":"O voice_id da voz do agente e de POST /tts."},"name":{"type":"string"},"languages":{"type":"array","items":{"type":"string"},"description":"Os idiomas que o provedor indica (pt-BR, en…); vazio quando ele não diz."},"gender":{"type":["string","null"],"description":"male, female ou neutral, quando o provedor diz."},"accent":{"type":["string","null"],"description":"Quando o provedor diz."},"preview_url":{"type":["string","null"],"format":"uri","description":"Uma amostra da voz, quando há."}}},"TtsRequest":{"type":"object","required":["provider","voice_id","text"],"properties":{"provider":{"type":"string","enum":["elevenlabs","cartesia"]},"voice_id":{"type":"string","maxLength":255},"text":{"type":"string","maxLength":1000},"speed":{"type":"number","minimum":0.25,"maximum":4,"default":1},"model":{"type":["string","null"]},"language":{"type":"string","default":"pt-BR"},"format":{"type":"string","enum":["mp3","wav"],"default":"mp3"}}},"SdpOffer":{"type":"object","required":["session"],"properties":{"session":{"type":"object","required":["sdp_type","sdp"],"properties":{"sdp_type":{"type":"string","const":"offer"},"sdp":{"type":"string","description":"O SDP completo, sem trickle ICE."}}}}},"SdpAnswer":{"type":"object","properties":{"sdp_type":{"type":"string","const":"answer"},"sdp":{"type":"string"}}},"MonitorToken":{"type":"object","properties":{"token":{"type":"string","description":"mon_…, para o navegador do supervisor; vale uma vez."},"ice_servers":{"type":"array","items":{"type":"object"},"description":"Para new RTCPeerConnection({ iceServers })."},"expires_at":{"type":"string","format":"date-time"}}},"AgentTestSession":{"type":"object","properties":{"id":{"type":"string"},"token":{"type":"string","description":"agt_…, para o navegador; vale uma vez."},"ice_servers":{"type":"array","items":{"type":"object"}},"expires_at":{"type":"string","format":"date-time"},"secret":{"type":"string","description":"Só sem number_id: o segredo que assina os pedidos do motor nesta chamada de teste."}}},"AgentEvent":{"type":"object","properties":{"object":{"type":"string","const":"voza"},"event":{"type":"string","enum":["call.agent.started","call.agent.state","call.transcript","call.agent.tool_call","call.metrics","call.supervision","call.agent.error","call.agent.declined","call.agent.ended"]},"event_id":{"type":"string","description":"O mesmo em cada tentativa: use-o para não processar um evento duas vezes."},"number":{"type":"object","description":"Como em number.status."},"call":{"type":"object","description":"Ausente numa chamada de teste.","properties":{"id":{"type":"string"},"call_id":{"type":"string"},"direction":{"type":"string"},"contact":{"type":"string"},"contact_name":{"type":["string","null"]},"agent_ref":{"type":"string"},"agent_session_id":{"type":["string","null"]}}},"test_session":{"type":"object","description":"Só numa chamada de teste.","properties":{"id":{"type":"string"},"agent_ref":{"type":"string"}}},"test":{"type":"boolean"},"data":{"type":"object","description":"O que o motor mandou: state (listening, thinking, speaking, handoff, handoff_timeout, supervised); speaker, text, start e end; name, duration_ms e result; as latências; monitor_id e mode; service, provider, status, category e action de um provedor que falhou (call.agent.error); reason, detail, mode e outcome de uma chamada que o agente recusou (call.agent.declined); e, no fim, reason, duration_seconds, ai_seconds, supervised_seconds, transcript, tools e usage."},"timestamp":{"type":"integer","description":"Segundos (Unix)."},"timestamp_ms":{"type":"integer","description":"O mesmo instante em milissegundos, para ordenar eventos do mesmo segundo."}}},"WebphoneToken":{"type":"object","properties":{"token":{"type":"string"},"expires_at":{"type":"string","format":"date-time"},"sdk_url":{"type":"string"}}},"WebphoneSession":{"type":"object","properties":{"session_id":{"type":"string","description":"O id desta sessão, o mesmo do evento claimed."},"label":{"type":["string","null"]},"number":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"phone":{"type":["string","null"]},"status":{"type":"string","enum":["starting","qr","connected","failed"]}}},"ice_servers":{"type":"array","description":"Para new RTCPeerConnection({ iceServers }). As credenciais do TURN vencem: peça a sessão de novo antes de cada chamada.","items":{"type":"object","properties":{"urls":{"type":"array","items":{"type":"string"}},"username":{"type":"string"},"credential":{"type":"string"}}}},"expires_at":{"type":"string","format":"date-time"}}},"WebhookEnvelope":{"type":"object","description":"O envelope da Meta. metadata.phone_number_id é o id do número na Voza, e metadata.external_ref, a sua referência, quando o número tem uma. value traz contacts, messages, statuses ou calls, e os errors da Meta, mesmo sozinhos.","properties":{"object":{"type":"string","const":"whatsapp_business_account"},"entry":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"changes":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","enum":["messages","calls"]},"value":{"type":"object"}}}}}}}}},"NumberStatusEvent":{"type":"object","properties":{"object":{"type":"string","const":"voza"},"event":{"type":"string","enum":["number.status","test"]},"number":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"external_ref":{"type":["string","null"]},"status":{"type":"string"},"status_reason":{"$ref":"#/components/schemas/StatusReason"},"phone":{"type":["string","null"]}}},"timestamp":{"type":"integer"}}}}}}