Visão Geral

A API do WhatsApp Medic Scheduler permite integração completa com o sistema de agendamento médico via WhatsApp com IA conversacional.

Base URL

http://localhost:5000

Blueprints

Blueprint Prefixo Descrição
agent /api Agente IA, pacientes, sistema
webhooks /api/v1/webhook Webhooks Twilio e Vonage
messages /api/v1/messages Envio de mensagens
fallback /fallback Transferência para humanos
rag /api/rag Sistema RAG (Retrieval)

Autenticação

A API utiliza Bearer Token para endpoints protegidos. Para webhooks, utilize os tokens de verificação dos provedores (Twilio/Vonage).

Header de Autenticação
Authorization: Bearer YOUR_API_TOKEN

Códigos de Erro

Código Status Descrição
200OKRequisição bem-sucedida
202AcceptedRequisição aceita (assíncrona)
400Bad RequestRequisição inválida
404Not FoundRecurso não encontrado
500Server ErrorErro interno do servidor
503Service UnavailableServiço indisponível

Agent - Health Check

GET /api/health

Verifica o status da API e do pool de conexões do banco de dados.

Response 200 OK

application/json
{
  "status": "healthy",
  "timestamp": "2025-12-06T10:00:00.000000",
  "database": {
    "pool_size": 5,
    "checked_in": 5,
    "checked_out": 0,
    "overflow": 0
  },
  "version": "1.0.0"
}

Agent - Fetch Patient Info

POST /api/fetch_and_set_patient_info

Busca informações completas do paciente via NetPacsConnector para popular o contexto do agente IA.

Request Body

application/json
{
  "number_whatsapp": "+5531999999999"
}

Response 200 OK

application/json
{
  "basic_patient_info": {
    "id": "12345",
    "name": "João da Silva",
    "number_whatsapp": "+5531999999999",
    "patient_social": "João"
  },
  "sensive_patient_info": {
    "sex": "M",
    "cpf": "12345678900",
    "rg": "MG1234567",
    "email": "joao@email.com",
    "altura": "175",
    "peso": "70",
    "birthdate": "1990/05/15"
  },
  "accessionNumber": "ACC12345",
  "protocolo": null,
  "solicitanteCrm": "123456",
  "solicitanteEstadoCrm": "SP",
  "solicitanteWorklist": "Dr. João Silva",
  "executanteCrm": null,
  "modality": "MR",
  "titulo": "RESSONÂNCIA MAGNÉTICA",
  "studyDateTimeString": null,
  "convenio": "Particular"
}

Errors

CódigoDescrição
400number_whatsapp não fornecido
404Paciente não encontrado
500Erro interno ao buscar dados

Agent - System State

GET /api/system/state

Retorna o estado atual do sistema (tokens, limites, status de funcionamento).

Response 200 OK

application/json
{
  "the_system_is_broken": false,
  "is_email_sent": false,
  "last_time_checked": "2025-12-06T10:00:00",
  "tokens_info": {
    "tokens_used": 15000,
    "tokens_limit": 100000,
    "max_tokens_limit": 500000,
    "users_using": 5,
    "users_ids": ["user1", "user2", "user3"]
  }
}
PUT /api/system/state

Atualiza o estado do sistema (destravar, resetar flags).

Request Body

application/json
{
  "the_system_is_broken": false,
  "is_email_sent": false,
  "tokens_limit": 100000,
  "max_tokens_limit": 500000
}

Agent - Tokens History

GET /api/system/tokens/history

Retorna histórico de consumo de tokens por dia.

Query Parameters

ParâmetroTipoObrigatórioDescrição
date string Não Data no formato YYYY-MM-DD (padrão: hoje)

Response 200 OK

{
  "date": "2025-12-06",
  "total_records": 25,
  "records": [
    {
      "created_at": "2025-12-06T08:30:00",
      "user_id": "user_abc123",
      "tokens_used": 1500
    }
  ]
}

Webhook - Twilio

POST /api/v1/webhook/twilio

Recebe mensagens de entrada do WhatsApp via Twilio e encaminha para o agente IA.

Request Body application/x-www-form-urlencoded

CampoTipoObrigatórioDescrição
FromstringSimNúmero de origem (whatsapp:+5511...)
BodystringSimConteúdo da mensagem
ProfileNamestringSimNome do perfil
TostringSimNúmero do bot

Response 200 OK

Retorna status 200 após processar a mensagem e enviar resposta via Twilio.

Webhook - Vonage

POST /api/v1/webhook/vonage

Recebe mensagens de entrada do WhatsApp via Vonage. Inclui deduplicação automática via Redis.

Importante: Vonage envia webhooks em duplicata para redundância. O sistema possui cache Redis/memória para prevenir processamento duplo.

Request Body

application/json
{
  "from": "5511999999999",
  "to": "5511888888888",
  "message_uuid": "abc123-def456-ghi789",
  "timestamp": "2025-12-06T10:00:00Z",
  "text": "Olá, gostaria de agendar uma consulta"
}

Response 200 OK

Retorna status 200 após processar a mensagem e enviar resposta via Vonage.

Webhook - Vonage Status

POST /api/v1/webhook/vonage/message-status

Recebe atualizações de status das mensagens enviadas (delivered, failed, etc.).

Request Body

{
  "message_uuid": "abc123-def456-ghi789",
  "to": "5511999999999",
  "status": "delivered",
  "error": null,
  "timestamp": "2025-12-06T10:01:00Z"
}

Messages - Twilio Model

POST /api/v1/messages/twilio/model/message

Envia mensagem inicial modelada via Twilio Templates (mensagens transacionais).

Request Body

{
  "patient_name": "João da Silva"
}

Response 202 Accepted

{
  "id": "SM1234567890abcdef",
  "status": "queued",
  "to": "whatsapp:+5511999999999",
  "date_created": "2025-12-06 10:00:00"
}

Messages - Twilio Spare

POST /api/v1/messages/twilio/spare/message

Endpoint auxiliar para enviar mensagens via Twilio (teste/debug).

Request Body

{
  "to": "whatsapp:+5511999999999",
  "body": "Texto da mensagem de teste"
}

Messages - Vonage Spare

POST /api/v1/messages/vonage/spare/message

Envia mensagem via Vonage WhatsApp API.

Request Body

{
  "user_number": "5511999999999",
  "to_number": "5511888888888",
  "body": "Olá, esta é uma mensagem de teste."
}

Fallback - Transfer to Human

POST /fallback/transferToHuman

Transfere uma conversa do agente IA para um atendente humano. Cria um ticket na fila de atendimento.

Request Body

application/json
{
  "number_whatsapp": "+5511999999999",
  "session_id": "abc123def456",
  "reason": "Paciente solicitou falar com um humano",
  "summary": "Conversa sobre reagendamento de consulta",
  "patient_name": "João da Silva",
  "patient_id": "123e4567-e89b-12d3-a456-426614174000"
}

Response 202 Accepted

{
  "status": "accepted",
  "ticket_id": "HUM-20251206143022-abc123de",
  "message": "Sua solicitação foi aceita. Um atendente entrará em contato em breve.",
  "queue_position": 3,
  "estimated_wait_time": 9,
  "conversation_context": {
    "patient_info": {
      "id": "123e4567...",
      "name": "João da Silva",
      "phone": "+5511999999999"
    },
    "reason_for_transfer": "Paciente solicitou falar com um humano",
    "conversation_summary": "Conversa sobre reagendamento"
  }
}

Fallback - Ticket Status

GET /fallback/getTicketStatus/{ticket_id}

Obtém o status atual de um ticket de transferência.

Path Parameters

ParâmetroTipoDescrição
ticket_idstringID do ticket (ex: HUM-20251206143022-abc123de)

Response 200 OK

{
  "ticket_id": "HUM-20251206143022-abc123de",
  "status": "waiting",
  "position_in_queue": 2,
  "estimated_wait_time": 6,
  "actual_wait_time_seconds": 180,
  "created_at": "2025-12-06T14:30:22",
  "started_at": null,
  "reason": "Paciente solicitou falar com um humano",
  "message": "Você está na posição 2 da fila. Tempo estimado: 6 minutos."
}

Fallback - Queue Status

GET /fallback/queue/status

Obtém o status geral da fila de atendimento humano.

Response 200 OK

{
  "total_tickets": 50,
  "active_agents": 3,
  "average_wait_time": 300,
  "tickets_waiting": 5,
  "tickets_in_progress": 3,
  "tickets_resolved": 42,
  "server_time": "2025-12-06T14:35:00"
}

Fallback - Acknowledge Transfer

POST /fallback/acknowledgeTransfer

Confirma que um atendente humano iniciou o atendimento.

Request Body

{
  "ticket_id": "HUM-20251206143022-abc123de",
  "agent_name": "Maria Silva",
  "agent_id": "agent_123"
}

Response 200 OK

{
  "status": "success",
  "message": "Atendimento iniciado por Maria Silva",
  "ticket_id": "HUM-20251206143022-abc123de",
  "agent_name": "Maria Silva",
  "started_at": "2025-12-06T14:35:00"
}

Fallback - Close Ticket

POST /fallback/closeTicket

Encerra um ticket de atendimento humano.

Request Body

{
  "ticket_id": "HUM-20251206143022-abc123de",
  "resolution": "Agendamento realizado com sucesso",
  "agent_id": "agent_123"
}

Response 200 OK

{
  "status": "success",
  "message": "Ticket encerrado com sucesso",
  "ticket_id": "HUM-20251206143022-abc123de",
  "resolution": "Agendamento realizado com sucesso",
  "closed_at": "2025-12-06T14:45:00"
}

Fallback - Agent Stats

GET /fallback/agent/{agent_id}/stats

Obtém estatísticas de um agente específico.

Response 200 OK

{
  "agent_id": "agent_123",
  "agent_name": "Maria Silva",
  "total_tickets": 150,
  "tickets_resolved": 145,
  "average_resolution_time": 420,
  "current_active_tickets": 2
}

RAG - Health Check

GET /api/rag/health

Verifica saúde do sistema RAG (Retrieval-Augmented Generation).

Response 200 OK

{
  "status": "healthy",
  "message": "Sistema RAG operacional",
  "chroma_db": "connected",
  "documents_indexed": 25
}

RAG - Stats

GET /api/rag/stats

Retorna estatísticas do sistema RAG.

Response 200 OK

{
  "status": "success",
  "total_documents": 25,
  "total_chunks": 450,
  "total_size_mb": 2.5,
  "collection_name": "whatsapp_medic_docs",
  "embedding_model": "text-embedding-ada-002",
  "max_files": 100,
  "chunk_size": 1000,
  "chunk_overlap": 200,
  "documents_by_type": {
    ".md": 15,
    ".txt": 5,
    ".py": 5
  },
  "top_documents": [
    {"file": "docs/api.md", "chunks": 45, "size_kb": 120}
  ]
}

RAG - Documents

GET /api/rag/documents

Lista todos os documentos indexados no sistema RAG.

POST /api/rag/documents

Upload e indexação de novo documento.

Request multipart/form-data

CampoTipoDescrição
filefileArquivo (.md, .txt, .py, .json, .yaml)
DELETE /api/rag/documents/{doc_id}

Remove documento do índice RAG.

RAG - Indexing

POST /api/rag/index

Dispara indexação manual de todos os arquivos do diretório docs/ de forma assíncrona.

Response 202 Accepted

{
  "status": "success",
  "message": "Indexação iniciada em background",
  "started_at": "2025-12-06T10:00:00",
  "info": "Use GET /api/rag/index/status para acompanhar o progresso"
}
GET /api/rag/index/status

Retorna status da indexação assíncrona.

Response 200 OK

{
  "status": "success",
  "indexing": {
    "is_running": false,
    "started_at": "2025-12-06T10:00:00",
    "completed_at": "2025-12-06T10:02:30",
    "status": "completed",
    "message": "Indexação concluída com sucesso",
    "stats": {
      "total_documents": 25,
      "total_chunks": 450
    }
  }
}
POST /api/rag/monitor/index-existing

Indexa todos os arquivos existentes no diretório monitorado.