DevelopersAPI TEMA v2
Rapidoc · TEMA v2 · VitalCheck AI

VitalCheck AI

Check-up preventivo gerado por IA a partir do histórico clínico do beneficiário: consentimento LGPD, elegibilidade, geração do relatório e acompanhamento.

Escopo do parceiro de consumo

Só a experiência do beneficiário

O parceiro de consumo constrói apenas a experiência do beneficiário. Gestão, relatórios agregados e consumo por período ficam no Manager da Rapidoc — o parceiro não integra nada disso.

Headers

Todas as chamadas levam os três headers da API TEMA v2:

HeaderValor
AuthorizationBearer <token> — do parceiro, fornecido pela Rapidoc
clientId<uuid-do-cliente> — sempre o do próprio cliente
Content-Typeapplication/vnd.rapidoc.tema-v2+json

Datas nas respostas

Todo campo de data das respostas (generatedAt, grantedAt, revokedAt, renewsAt, campos de comparação…) já vem formatado como string dd/MM/yyyy HH:mm:ss no fuso GMT-3 (ex.: "01/09/2026 14:20:05") — não é epoch e não precisa de new Date(...). Os valores enviados na query (dateInitial/dateFinal) seguem o formato dd/MM/yyyy.

VitalCheck AI

Gera um relatório de check-up preventivo a partir do histórico clínico consolidado do beneficiário, usando IA. Exige o produto vitalcheck ativo no cliente — sem isso todos os endpoints abaixo devolvem 422.

Ordem de integração:

  1. Consentimento — registrar o aceite do termo LGPD com POST /beneficiary-consents/{uuid}/grant.
  2. Elegibilidade — checar o que falta com GET /beneficiary-vitalcheck-reports/{uuid}/eligibility (não chama IA, não persiste nada).
  3. Check-up — gerar o relatório com POST /beneficiary-vitalcheck-reports/{uuid}.
  4. Acompanhamento — listar relatórios, comparar dois check-ups, consultar a cota do mês.

O check-up só é gerado com consentimento LGPD vigente. POST /grant é idempotente para a mesma termVersion: repetir a chamada devolve o consentimento vigente sem criar outro; se a versão mudou, revoga o anterior e cria um novo.

EndpointO que faz
GET /tema/api/beneficiary-consents/{uuid}Consulta se há consentimento vigente, a versão do termo e quando foi concedido/revogado
POST /tema/api/beneficiary-consents/{uuid}/grantConcede (ou renova) o consentimento. Corpo: { "termVersion": "..." }
POST /tema/api/beneficiary-consents/{uuid}/revokeRevoga o consentimento vigente. Sem consentimento ativo: 422

Exemplos de chamada

Conceder consentimento — POST /tema/api/beneficiary-consents/{uuid}/grant

curl · POST /beneficiary-consents/{uuid}/grant
curl --location '{{BASE_URL}}/tema/api/beneficiary-consents/UUID_DO_BENEFICIARIO/grant' \
  --header 'Authorization: Bearer SEU_TOKEN' \
  --header 'clientId: UUID_DO_CLIENTE' \
  --header 'Content-Type: application/vnd.rapidoc.tema-v2+json' \
  --data '{ "termVersion": "2026-08-01" }'
json · resposta 200
{
  "beneficiaryUuid": "UUID_DO_BENEFICIARIO",
  "hasActiveConsent": true,
  "termVersion": "2026-08-01",
  "grantedAt": "01/09/2026 14:03:11",
  "revokedAt": null
}

Consultar consentimento vigente — GET /tema/api/beneficiary-consents/{uuid}

curl · GET /beneficiary-consents/{uuid}
curl --location '{{BASE_URL}}/tema/api/beneficiary-consents/UUID_DO_BENEFICIARIO' \
  --header 'Authorization: Bearer SEU_TOKEN' \
  --header 'clientId: UUID_DO_CLIENTE' \
  --header 'Content-Type: application/vnd.rapidoc.tema-v2+json'

Revogar consentimento — POST /tema/api/beneficiary-consents/{uuid}/revoke

curl · POST /beneficiary-consents/{uuid}/revoke
curl --location '{{BASE_URL}}/tema/api/beneficiary-consents/UUID_DO_BENEFICIARIO/revoke' \
  --header 'Authorization: Bearer SEU_TOKEN' \
  --header 'clientId: UUID_DO_CLIENTE' \
  --header 'Content-Type: application/vnd.rapidoc.tema-v2+json'

Check-up por IA

POST/tema/api/beneficiary-vitalcheck-reports/{uuid}

Executa a cascata de validações, consolida o prontuário desde o último check-up, gera o relatório estruturado via IA (score, alertas, recomendações), persiste e registra o custo. Se não houver novidade desde o último check-up, não chama a IA e devolve generated: false.

Validações, nesta ordem (422 ao falhar):

ValidaçãoEfeito
Produto vitalcheck ativo no clienteObrigatória
Beneficiário com pelo menos 1 consulta registradaObrigatória
Consentimento LGPD vigenteObrigatória
Cota mensal configurada e não atingidaObrigatória
curl · POST /beneficiary-vitalcheck-reports/{uuid}
curl --location '{{BASE_URL}}/tema/api/beneficiary-vitalcheck-reports/UUID_DO_BENEFICIARIO' \
  --header 'Authorization: Bearer SEU_TOKEN' \
  --header 'clientId: UUID_DO_CLIENTE' \
  --header 'Content-Type: application/vnd.rapidoc.tema-v2+json'

Resposta 200 — relatório gerado:

json · resposta 200
{
  "uuid": "UUID_DO_RELATORIO",
  "beneficiaryUuid": "UUID_DO_BENEFICIARIO",
  "generated": true,
  "isFirstCheckup": false,
  "score": 82,
  "alertsCount": 1,
  "recommendationsCount": 3,
  "vitalscanUsed": true,
  "reportContent": {
    "score": 82,
    "scoreRationale": "...",
    "summary": "...",
    "riskFactors": ["..."],
    "alerts": [{ "...": "..." }],
    "vitalSigns": { "...": "..." },
    "recommendations": [{ "...": "..." }],
    "futureInvestigations": ["..."]
  },
  "llmModel": "claude-...",
  "generatedAt": "01/09/2026 14:20:05"
}

Resposta 200 — sem novidade desde o último check-up (IA não acionada):

json · resposta 200
{ "beneficiaryUuid": "UUID_DO_BENEFICIARIO", "generated": false, "reason": "no_new_data" }

reportContent já vem como objeto estruturado (score, scoreRationale, summary, riskFactors, alerts, vitalSigns, recommendations, futureInvestigations) — sem precisar de JSON.parse. Resposta da IA malformada, ou score fora de 0–100: 422 (o custo já incorrido é registrado mesmo assim).

Demais operações

EndpointO que faz
GET /tema/api/beneficiary-vitalcheck-reports/{uuid}Lista os relatórios já gerados, mais recente primeiro
GET .../{uuid}/compare?reportUuidA=&reportUuidB=Compara dois check-ups via IA. Sem os dois UUIDs, compara os 2 mais recentes
GET .../{uuid}/comparisonsLista os comparativos já salvos (não chama IA)
GET .../{uuid}/quotaCota do mês: usados, limite e data de renovação
GET .../{uuid}/eligibilityRoda a mesma cascata do check-up sem chamar IA nem persistir, reportando cada gate

Comparar dois check-ups — GET /tema/api/beneficiary-vitalcheck-reports/{uuid}/compare

curl · GET .../compare
curl --location '{{BASE_URL}}/tema/api/beneficiary-vitalcheck-reports/UUID_DO_BENEFICIARIO/compare?reportUuidA=UUID_RELATORIO_A&reportUuidB=UUID_RELATORIO_B' \
  --header 'Authorization: Bearer SEU_TOKEN' \
  --header 'clientId: UUID_DO_CLIENTE' \
  --header 'Content-Type: application/vnd.rapidoc.tema-v2+json'

Cota do mês — GET /tema/api/beneficiary-vitalcheck-reports/{uuid}/quota

curl · GET .../quota
curl --location '{{BASE_URL}}/tema/api/beneficiary-vitalcheck-reports/UUID_DO_BENEFICIARIO/quota' \
  --header 'Authorization: Bearer SEU_TOKEN' \
  --header 'clientId: UUID_DO_CLIENTE' \
  --header 'Content-Type: application/vnd.rapidoc.tema-v2+json'
json · resposta 200
{
  "beneficiaryUuid": "UUID_DO_BENEFICIARIO",
  "used": 2,
  "limit": 4,
  "unlimited": false,
  "renewsAt": "01/10/2026 00:00:00"
}

limit: null e unlimited: true quando não há cota mensal aplicada ao beneficiário — used continua contando normalmente. renewsAt é sempre o dia 1º do próximo mês.

Elegibilidade — GET /tema/api/beneficiary-vitalcheck-reports/{uuid}/eligibility

curl · GET .../eligibility
curl --location '{{BASE_URL}}/tema/api/beneficiary-vitalcheck-reports/UUID_DO_BENEFICIARIO/eligibility' \
  --header 'Authorization: Bearer SEU_TOKEN' \
  --header 'clientId: UUID_DO_CLIENTE' \
  --header 'Content-Type: application/vnd.rapidoc.tema-v2+json'
json · resposta 200
{
  "beneficiaryUuid": "UUID_DO_BENEFICIARIO",
  "eligible": false,
  "blockReason": "no_consent",
  "hasActiveProduct": true,
  "hasAppointment": true,
  "hasActiveConsent": false,
  "consentTermVersion": null,
  "monthlyUsed": 0,
  "monthlyLimit": 4,
  "withinMonthlyLimit": true,
  "hasNewData": true,
  "isFirstCheckup": true,
  "canRequestEmergency": true,
  "canDoVitalScan": true
}

eligible: true quando blockReason é null. Valores possíveis: no_product, no_appointment, no_consent, monthly_limit_not_configured, monthly_limit_reached, no_new_data. canDoVitalScan indica se o parceiro pode oferecer o VitalScan como complemento.

Passo a passo de implementação

Sequência mínima para integrar o VitalCheck AI — os detalhes de cada chamada estão nas seções acima.

Passo a passo · VitalCheck AI
  1. 1
    GET/beneficiary-consents/{uuid}

    Verifica se já existe consentimento LGPD vigente

  2. 2
    POST/beneficiary-consents/{uuid}/grant

    Registra o aceite do termo (idempotente por versão)

  3. 3
    GET/beneficiary-vitalcheck-reports/{uuid}/eligibility

    Confere os gates antes de habilitar o botão de gerar

  4. 4
    POST/beneficiary-vitalcheck-reports/{uuid}

    Gera o check-up: consolida o prontuário e chama a IA

  5. 5
    GET/beneficiary-vitalcheck-reports/{uuid}

    Lista o histórico de check-ups já gerados

  6. 6
    GET/beneficiary-vitalcheck-reports/{uuid}/quota

    Mostra quantos check-ups restam no mês

Uso nas telas do app

Experiência do beneficiário: o que cada tela do app chama.

#EndpointUso na tela
1GET/tema/api/beneficiary-consents/{uuid}Ao abrir o VitalCheck: decidir se mostra o termo ou segue direto; exibir “consentimento dado em X”.
2POST/tema/api/beneficiary-consents/{uuid}/grantUsuário aceita o termo → registro. Idempotente para a mesma termVersion.
3POST/tema/api/beneficiary-consents/{uuid}/revokeBotão “revogar consentimento” (LGPD). Pouco uso, mas obrigatório expor.
4GET/tema/api/beneficiary-vitalcheck-reports/{uuid}/eligibilityHabilitar ou desabilitar o botão “Gerar check-up” e mostrar o motivo (no_consent, monthly_limit_reached, no_new_data…) sem disparar um POST que falha.
5POST/tema/api/beneficiary-vitalcheck-reports/{uuid}A ação em si. Tratar generated: false / reason: "no_new_data" como estado normal, não erro. reportContent já vem como objeto estruturado (score, scoreRationale, summary, riskFactors, alerts, vitalSigns, recommendations, futureInvestigations) — sem JSON.parse.
6GET/tema/api/beneficiary-vitalcheck-reports/{uuid}Tela de histórico (score + data) e origem do seletor de comparação.
7GET/tema/api/beneficiary-vitalcheck-reports/{uuid}/quota“2 de 4 este mês, renova em 01/10” e travar o botão ao atingir o limite. Com cota ilimitada, a resposta traz unlimited: true e limit: null — trate como “sem teto” em vez de esconder o card.
8GET/tema/api/beneficiary-vitalcheck-reports/{uuid}/compareGET/tema/api/beneficiary-vitalcheck-reports/{uuid}/comparisonsse oferecer a tela de compararcompare gera o comparativo por IA e persiste; comparisons lista o que já foi salvo, sem chamar a IA de novo. comparisonText também vem como objeto estruturado (summary, unchanged, improved, worsened).

Apresentação de telas

Mockup para visualizar como o fluxo aparece para o beneficiário e a qual chamada cada tela corresponde. Não é a UI real.

1 / 6
VitalCheck AI
Consentimento LGPD

Seu check-up analisa dados de saúde. Precisamos do seu aceite do termo (versão 2026-08-01) para continuar.

O consentimento fica vigente até você revogar — não é pedido a cada check-up.
Li e aceito o termo
GET + POST

O app consulta se já há consentimento vigente; se não, exibe o termo e registra o aceite (idempotente para a mesma versão).

GET /beneficiary-consents/{uuid} · POST …/grant

Checklist

Valide em sandbox antes de ir para produção. Os itens marcados ficam salvos neste navegador.

0 / 2