Introdução

Bem-vindo à documentação da API MedReader. Esta API REST permite que você processe prescrições médicas de forma inteligente, extraindo informações estruturadas de imagens e PDFs.

Base URL

https://api.medreader.com.br

Formato de Dados

Todas as requisições e respostas utilizam JSON, exceto o upload de arquivos que utiliza multipart/form-data.

Autenticação

A API utiliza autenticação baseada em JWT (JSON Web Token). Você deve primeiro obter um token através do endpoint de login e incluí-lo no header Authorization de todas as requisições subsequentes.

POST /api/v1/auth/login

Descrição

Autentica um usuário e retorna um token JWT para acesso aos demais endpoints.

Headers

Content-Type: application/json
X-Tenant-ID: {seu-tenant-id}

Request Body

{
  "email": "usuario@exemplo.com",
  "password": "sua-senha-segura"
}

Response (200 OK)

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "user": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "João Silva",
    "email": "usuario@exemplo.com",
    "phone": "+5511999999999"
  }
}

Possíveis Erros

Código Error Descrição
400 validation_error Email ou senha não fornecidos ou inválidos
401 invalid_credentials Email ou senha incorretos
401 tenant_invalid Tenant ausente ou inválido
429 too_many_attempts Muitas tentativas de autenticação falhadas

Endpoints

Folders

Gerencie pastas para organizar suas prescrições médicas.

POST /api/v1/folders

Descrição

Cria uma nova pasta para organizar prescrições.

Permissões Necessárias

Este endpoint requer autenticação via token JWT. O usuário deve estar autenticado e ter acesso ao tenant especificado.

Normalização de Nome

O nome da pasta é automaticamente normalizado para formato URL-safe:

  • Acentos são removidos (ã → a, é → e, ç → c)
  • Convertido para minúsculas
  • Espaços e caracteres especiais são substituídos por hífen (-)
  • Múltiplos hífens são reduzidos a um único
  • Hífens no início e fim são removidos

Exemplo: "Pacientes Cardiologia" → "pacientes-cardiologia"

Exemplo: "Documentos Ações 2025" → "documentos-acoes-2025"

Headers

Content-Type: application/json
Authorization: Bearer {seu-token-jwt}
X-Tenant-ID: {seu-tenant-id}

Request Body

{
  "folder_name": "Pacientes Cardiologia",
  "parent_folder_id": "550e8400-e29b-41d4-a716-446655440000"
}

Nota: O nome será normalizado para "pacientes-cardiologia" automaticamente.

Nota: O campo parent_folder_id é opcional. Se não fornecido, a pasta será criada na raiz.

Response (201 Created)

{
  "id": "660e8400-e29b-41d4-a716-446655440001",
  "folder_name": "pacientes-cardiologia",
  "parent_folder_id": "550e8400-e29b-41d4-a716-446655440000",
  "full_path": "pacientes/pacientes-cardiologia",
  "created_at": "2024-01-18T14:30:00Z",
  "updated_at": "2024-01-18T14:30:00Z"
}

Possíveis Erros

Código Error Descrição
400 validation_error Nome da pasta é obrigatório
401 unauthorized Usuário não autorizado
409 folder_name_duplicate Já existe uma pasta com este nome no mesmo nível
409 parent_folder_not_found Pasta pai não encontrada
GET /api/v1/folders/:folder-id

Descrição

Busca informações detalhadas de uma pasta específica, incluindo subpastas e contagem de arquivos.

Permissões Necessárias

Este endpoint requer autenticação via token JWT. O usuário deve estar autenticado e ter acesso ao tenant especificado.

Headers

Authorization: Bearer {seu-token-jwt}
X-Tenant-ID: {seu-tenant-id}

Path Parameters

  • folder-id - ID da pasta (UUID)

Response (200 OK)

{
  "id": "660e8400-e29b-41d4-a716-446655440001",
  "folder_name": "pacientes-cardiologia",
  "parent_folder_id": "550e8400-e29b-41d4-a716-446655440000",
  "created_at": "2024-01-18T14:30:00Z",
  "updated_at": "2024-01-18T14:30:00Z",
  "full_path": "pacientes/pacientes-cardiologia",
  "prescription_files_count": 15,
  "validation_rules_count": 3,
  "child_folders": [
    {
      "id": "770e8400-e29b-41d4-a716-446655440002",
      "folder_name": "janeiro-2024",
      "created_at": "2024-01-18T15:00:00Z",
      "updated_at": "2024-01-18T15:00:00Z",
      "full_path": "pacientes/pacientes-cardiologia/janeiro-2024",
      "prescription_files_count": 8,
      "validation_rules_count": 3
    }
  ]
}

Contador de Regras de Validação

O campo validation_rules_count indica quantas regras de validação estão configuradas para esta pasta.

Para obter os detalhes das regras, use o endpoint GET /api/v1/folders/:folder-id/validation-rules.

Possíveis Erros

Código Error Descrição
400 bad_request ID da pasta é obrigatório
401 unauthorized Usuário não autorizado
404 folder_not_found Pasta não encontrada

Regras de Validação

Configure regras de validação para pastas. Estas regras serão aplicadas automaticamente a todas as prescrições enviadas para a pasta.

POST /api/v1/folders/:folder-id/validation-rules

Descrição

Cria regras de validação para uma pasta específica. As regras serão aplicadas automaticamente a todas as prescrições enviadas para esta pasta.

Permissões Necessárias

Este endpoint requer autenticação via token JWT. O usuário deve estar autenticado e ter acesso ao tenant especificado.

Campos Validáveis e Regras

Cada campo aceita um conjunto específico de regras. Campos com exact, partial_match ou range_match exigem que um argumento correspondente seja enviado no form-data durante o upload da prescrição.

Campo Regras disponíveis Argumento no upload O que valida
patient_name required · exact · partial_match Sim (para exact e partial_match). Aceita múltiplos valores. Nome do paciente. partial_match usa IA para verificar similaridade; exact normaliza e compara diretamente (sem acentos ou espaços extras).
patient_document required · exact · partial_match Sim (para exact e partial_match) Documento do paciente (CPF, RG, etc). required verifica presença; exact compara o valor normalizado.
doctor_name required · exact · partial_match Sim (para exact e partial_match) Nome do médico na prescrição. partial_match usa IA para verificar similaridade; exact normaliza e compara diretamente (sem acentos ou espaços extras).
doctor_document required · exact · partial_match Sim (para exact e partial_match) Documento do médico (CRM, CRN, CRO). Ex: doctor_document=CRM-SP 12345.
doctor_document_type required · exact Sim (para exact) Tipo do documento do médico. CRM, CRN ou CRO. Ex: doctor_document_type=CRM.
doctor_document_state required · exact Sim (para exact) Estado de registro do documento do médico. Ex: doctor_document_state=SP.
doctor_signature required Não Verifica se a assinatura do médico está presente na prescrição.
doctor_stamp required Não Verifica se o carimbo do médico está presente na prescrição.
prescription_date required · exact · range_match Sim (para exact e range_match) Data da prescrição. exact: data exata no formato yyyy-MM-dd (ex: prescription_date=2025-03-15). range_match: intervalo no formato yyyy-MM-dd;yyyy-MM-dd (ex: prescription_date=2025-01-01;2025-03-31).
prescription_format handwritten · digitized · electronic Não (a regra é o próprio valor) Formato físico da prescrição: manuscrita, digitalizada ou eletrônica. Ex: "rule": "electronic".
prescription_reading_confidence high · medium · low Não (a regra é o próprio valor) Nível de confiança de leitura atribuído pela IA: alta, média ou baixa.
prescription_min_confidence_score {número inteiro 0–100} Não (o valor mínimo vai direto no campo rule) Score mínimo de confiança exigido. Ex: "rule": "90" — a prescrição deve ter score ≥ 90 para ser aprovada.

Headers

Content-Type: application/json
Authorization: Bearer {seu-token-jwt}
X-Tenant-ID: {seu-tenant-id}

Path Parameters

  • folder-id - ID da pasta (UUID)

Request Body

{
  "validation_rules": [
    {
      "field": "patient_name",
      "rule": "partial_match"
    },
    {
      "field": "doctor_document",
      "rule": "exact"
    },
    {
      "field": "prescription_date",
      "rule": "range_match"
    },
    {
      "field": "prescription_min_confidence_score",
      "rule": "90"
    },
    {
      "field": "prescription_format",
      "rule": "electronic"
    },
    {
      "field": "doctor_signature",
      "rule": "required"
    }
  ]
}

Response (201 Created)

{
  "validation_rules": [
    {
      "id": "aa0e8400-e29b-41d4-a716-446655440010",
      "folder_id": "660e8400-e29b-41d4-a716-446655440001",
      "field": "patient_name",
      "rule": "partial_match",
      "created_at": "2024-01-18T17:00:00Z",
      "updated_at": "2024-01-18T17:00:00Z"
    },
    {
      "id": "bb0e8400-e29b-41d4-a716-446655440011",
      "folder_id": "660e8400-e29b-41d4-a716-446655440001",
      "field": "prescription_min_confidence_score",
      "rule": "90",
      "created_at": "2024-01-18T17:00:00Z",
      "updated_at": "2024-01-18T17:00:00Z"
    }
  ]
}

Possíveis Erros

Código Error Descrição
400 validation_error Dados inválidos ou campo/regra não suportados
401 unauthorized Usuário não autorizado
404 folder_not_found Pasta não encontrada
409 validation_rule_already_exists Já existe uma regra para este campo nesta pasta
GET /api/v1/folders/:folder-id/validation-rules

Descrição

Lista todas as regras de validação configuradas para uma pasta específica, incluindo regras herdadas de pastas pai.

Permissões Necessárias

Este endpoint requer autenticação via token JWT. O usuário deve estar autenticado e ter acesso ao tenant especificado.

Herança de Regras

As regras de validação são herdadas da hierarquia de pastas. Se uma pasta pai tem regras configuradas, elas serão aplicadas a todas as subpastas, a menos que sejam sobrescritas.

Prioridade: Regras da pasta atual têm prioridade sobre regras de pastas pai.

Headers

Authorization: Bearer {seu-token-jwt}
X-Tenant-ID: {seu-tenant-id}

Path Parameters

  • folder-id - ID da pasta (UUID)

Response (200 OK)

{
  "validation_rules": [
    {
      "field": "patient_name",
      "rule": "partial_match"
    },
    {
      "field": "prescription_min_confidence_score",
      "rule": "90"
    },
    {
      "field": "doctor_signature",
      "rule": "required"
    }
  ]
}

Possíveis Erros

Código Error Descrição
400 bad_request ID da pasta é obrigatório
401 unauthorized Usuário não autorizado
404 folder_not_found Pasta não encontrada

Prescrições

Faça upload e consulte resultados de análise de prescrições médicas.

POST /api/v1/prescription-files

Descrição

Faz upload de um arquivo de prescrição médica para processamento. O arquivo será processado de forma assíncrona e o resultado será enviado via webhook.

Permissões Necessárias

Este endpoint requer autenticação via token JWT. O usuário deve estar autenticado e ter acesso ao tenant especificado.

Headers

Content-Type: multipart/form-data
Authorization: Bearer {seu-token-jwt}
X-Tenant-ID: {seu-tenant-id}

Form Data

  • folder_id - ID da pasta onde o arquivo será armazenado (UUID, obrigatório)
  • file - Arquivo da prescrição (obrigatório)
  • {field_name} - Argumentos de validação dinâmicos (opcional)

Argumentos de Validação

Passe argumentos dinâmicos no form-data para regras do tipo exact, partial_match e range_match. O nome do campo deve corresponder ao campo configurado na regra de validação da pasta.

Exemplos:

  • patient_name=Maria Silva — para regras exact ou partial_match
  • patient_name=Maria Silva + patient_name=Maria S. Santos — múltiplos valores aceitos para patient_name (útil para dependentes de plano de saúde)
  • doctor_document=CRM-SP 12345 — para regra exact no documento do médico
  • prescription_date=2025-03-15 — para regra exact (formato yyyy-MM-dd)
  • prescription_date=2025-01-01;2025-03-31 — para regra range_match (formato yyyy-MM-dd;yyyy-MM-dd)

Estes valores serão comparados com as informações extraídas da prescrição pela IA.

Formatos Suportados

  • PDF (application/pdf)
  • JPEG (image/jpeg)
  • PNG (image/png)
  • TIFF (image/tiff)

Limitações de Arquivo

  • Tamanho máximo: 10 MB (10.485.760 bytes)
  • Arquivos vazios não são permitidos
  • Formatos não suportados serão rejeitados

Response (202 Accepted)

{
  "id": "880e8400-e29b-41d4-a716-446655440003",
  "folder_id": "660e8400-e29b-41d4-a716-446655440001",
  "file_path": "prescriptions/2024/01/18/prescription-123.pdf",
  "file_type": "application/pdf",
  "file_size": 245678,
  "original_filename": "prescricao-paciente.pdf",
  "processed": false,
  "uploaded_at": "2024-01-18T16:00:00Z",
  "message": "File uploaded successfully and will be processed asynchronously"
}

Possíveis Erros

Código Error Descrição
400 bad_request Arquivo ou folder_id não fornecido, formato não suportado, arquivo vazio ou tamanho excedido
400 file_size_exceeds_limit Tamanho do arquivo excede o limite máximo de 10 MB
400 file_empty Arquivo está vazio
400 unsupported_file_type Tipo de arquivo não suportado
401 unauthorized Usuário não autorizado
GET /api/v1/prescriptions/:prescription-id/result

Descrição

Busca o resultado detalhado de análise de uma prescrição específica pelo seu ID.

Permissões Necessárias

Este endpoint requer autenticação via token JWT. O usuário deve estar autenticado e ter acesso ao tenant especificado.

Headers

Authorization: Bearer {seu-token-jwt}
X-Tenant-ID: {seu-tenant-id}

Path Parameters

  • prescription-id - ID da prescrição (UUID)

Response (200 OK)

{
  "id": "880e8400-e29b-41d4-a716-446655440003",
  "created_at": "2024-01-18T16:00:00Z",
  "prescription_confidence_score": 95,
  "prescription_confidence_notes": "Prescrição clara e legível",
  "status": "completed",
  "folder_id": "660e8400-e29b-41d4-a716-446655440001",
  "folder_fullpath": "pacientes/pacientes-cardiologia",
  "validation_results": [
    {
      "field": "patient_name",
      "read_value": "Maria Silva Santos",
      "want_value": "Maria Silva",
      "match": true
    },
    {
      "field": "prescription_min_confidence_score",
      "read_value": "95",
      "want_value": "90",
      "match": true
    },
    {
      "field": "doctor_signature",
      "read_value": "true",
      "want_value": "required",
      "match": true
    }
  ]
}

Resultados de Validação

O campo validation_results contém os resultados das validações aplicadas à prescrição. Cada resultado inclui:

  • field: Campo validado
  • read_value: Valor lido da prescrição pelo sistema
  • want_value: Valor esperado ou tipo de validação
  • match: Indica se a validação passou (true) ou falhou (false)

Nota: Se o status for processing, o array validation_results estará vazio.

Campos da Resposta

Campo Tipo Descrição
id string ID único da prescrição
created_at timestamp Data e hora de criação do resultado
prescription_confidence_score integer Pontuação de confiança da leitura (0-100), pode ser null
prescription_confidence_notes string Notas sobre a confiança da leitura, pode ser null
status string Status do processamento (processing, completed, error)
folder_id string ID da pasta onde a prescrição está armazenada
folder_fullpath string Caminho completo da pasta
validation_results array Lista de resultados de validações aplicadas (vazio se status = processing)

Possíveis Erros

Código Error Descrição
400 bad_request ID da prescrição é obrigatório
401 unauthorized Usuário não autorizado
404 prescription_file_not_found Prescrição não encontrada
GET /api/v1/prescriptions/results?folder-id=:folder-id

Descrição

Lista todos os resultados de análise de prescrições de uma pasta específica.

Permissões Necessárias

Este endpoint requer autenticação via token JWT. O usuário deve estar autenticado e ter acesso ao tenant especificado.

Headers

Authorization: Bearer {seu-token-jwt}
X-Tenant-ID: {seu-tenant-id}

Query Parameters

  • folder-id - ID da pasta (UUID, obrigatório)

Response (200 OK)

{
  "folder_id": "660e8400-e29b-41d4-a716-446655440001",
  "folder_fullpath": "/Pacientes/Pacientes Cardiologia",
  "results": [
    {
      "id": "990e8400-e29b-41d4-a716-446655440004",
      "status": "completed"
    },
    {
      "id": "aa0e8400-e29b-41d4-a716-446655440005",
      "status": "processing"
    },
    {
      "id": "bb0e8400-e29b-41d4-a716-446655440006",
      "status": "error"
    }
  ]
}

Possíveis Status

  • processing - Arquivo em processamento
  • completed - Processamento concluído com sucesso
  • error - Erro no processamento

Possíveis Erros

Código Error Descrição
400 bad_request Parâmetro folder-id é obrigatório
401 unauthorized Usuário não autorizado

Webhook de Resultados

Quando uma prescrição é processada, a API envia automaticamente o resultado para a URL de webhook configurada no seu tenant.

POST {sua-url-webhook-configurada}

Descrição

A MedReader enviará uma requisição POST para sua URL de webhook configurada sempre que uma prescrição for processada.

Headers

Content-Type: application/json
Authorization: Basic {base64(webhook_user:webhook_password)}

Nota: A autenticação utiliza Basic Auth. O header Authorization contém as credenciais webhook_user e webhook_password configuradas no seu tenant, codificadas em Base64 no formato user:password.

Payload

{
  "id": "cc0e8400-e29b-41d4-a716-446655440007",
  "created_at": "2024-01-18T16:30:00Z",
  "prescription_confidence_score": 95,
  "prescription_confidence_notes": "Prescrição clara e legível",
  "validation_results": [
    {
      "field": "patient_name",
      "read_value": "Maria Silva Santos",
      "want_value": "Maria Silva",
      "match": true
    },
    {
      "field": "prescription_min_confidence_score",
      "read_value": "95",
      "want_value": "90",
      "match": true
    },
    {
      "field": "doctor_signature",
      "read_value": "true",
      "want_value": "required",
      "match": true
    }
  ]
}

Resultados de Validação

O campo validation_results contém os resultados das validações aplicadas à prescrição. Cada resultado inclui:

  • field: Campo validado
  • read_value: Valor lido da prescrição pelo sistema
  • want_value: Valor esperado ou tipo de validação
  • match: Indica se a validação passou (true) ou falhou (false)

Nota: O array validation_results estará vazio se não houver regras de validação configuradas para a pasta da prescrição.

Campos do Payload

Campo Tipo Descrição
id string ID único da análise da prescrição
created_at timestamp Data e hora de criação da análise
prescription_confidence_score integer Pontuação de confiança da leitura (0-100)
prescription_confidence_notes string Notas sobre a confiança da análise da prescrição
validation_results array Lista de resultados de validações aplicadas (vazio se não houver regras configuradas)

Resposta Esperada

Seu webhook deve responder com status 200 OK para confirmar o recebimento. Caso contrário, a MedReader poderá tentar reenviar a notificação.

Configuração do Tenant

Cada tenant possui configurações específicas que controlam o comportamento da API, incluindo credenciais de armazenamento S3 e configurações de webhook. Você pode consultar e atualizar essas configurações através dos endpoints abaixo.

Permissões Necessárias

Os endpoints de configuração requerem permissões especiais de admin ou configurations. Usuários sem essas permissões receberão erro 401 (unauthorized).

GET /api/v1/tenant/configurations

Descrição

Consulta as configurações atuais do tenant.

Headers

Authorization: Bearer {seu-token-jwt}
X-Tenant-ID: {seu-tenant-id}

Response (200 OK)

{
  "s3_bucket_name": "medreader-prescriptions",
  "s3_region": "us-east-1",
  "s3_access_key_id": "AK****************LE",
  "s3_secret_access_key": "wJ**************************************EY",
  "s3_base_path": "tenant-123/prescriptions",
  "webhook_url": "https://seu-sistema.com/api/webhooks/medreader",
  "webhook_user": "we********er",
  "webhook_password": "we*******************et"
}

Ofuscamento de Dados Sensíveis

Por segurança, os seguintes campos são retornados parcialmente ofuscados:

  • s3_access_key_id
  • s3_secret_access_key
  • webhook_user
  • webhook_password

Regra: os 2 primeiros e os 2 últimos caracteres são preservados; os demais são substituídos por *. Valores com 4 ou menos caracteres retornam ****.

Exemplo: AKIAIOSFODNN7EXAMPLEAK****************LE

Para atualizar esses valores, utilize o endpoint PUT /api/v1/tenant/configurations.

Possíveis Erros

Código Error Descrição
401 unauthorized Usuário não possui permissões necessárias
404 tenant_configuration_not_found Configuração do tenant não encontrada
PUT /api/v1/tenant/configurations

Descrição

Atualiza as configurações do tenant. Todos os campos são opcionais - apenas os campos fornecidos serão atualizados.

Headers

Content-Type: application/json
Authorization: Bearer {seu-token-jwt}
X-Tenant-ID: {seu-tenant-id}

Request Body

{
  "s3_bucket_name": "medreader-prescriptions",
  "s3_region": "us-east-1",
  "s3_access_key_id": "AKIAIOSFODNN7EXAMPLE",
  "s3_secret_access_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
  "s3_base_path": "tenant-123/prescriptions",
  "webhook_url": "https://seu-sistema.com/api/webhooks/medreader",
  "webhook_user": "webhook-user",
  "webhook_password": "webhook-password-secret"
}

Nota: Todos os campos são opcionais. Envie apenas os campos que deseja atualizar.

Parâmetros de Configuração

Parâmetro Tipo Descrição
s3_bucket_name string Nome do bucket S3 para armazenamento de arquivos
s3_region string Região AWS do bucket S3
s3_access_key_id string Access Key ID para acesso ao S3
s3_secret_access_key string Secret Access Key para acesso ao S3
s3_base_path string Caminho base no bucket S3
webhook_url string URL para receber notificações de prescrições processadas
webhook_user string Usuário para autenticação Basic Auth do webhook
webhook_password string Senha para autenticação Basic Auth do webhook

Response (200 OK)

{
  "s3_bucket_name": "medreader-prescriptions",
  "s3_region": "us-east-1",
  "s3_access_key_id": "AK****************LE",
  "s3_secret_access_key": "wJ**************************************EY",
  "s3_base_path": "tenant-123/prescriptions",
  "webhook_url": "https://seu-sistema.com/api/webhooks/medreader",
  "webhook_user": "we********er",
  "webhook_password": "we*******************et"
}

Nota: Os campos sensíveis na resposta são ofuscados com a mesma regra do GET — 2 primeiros e 2 últimos caracteres preservados, demais substituídos por *.

Possíveis Erros

Código Error Descrição
400 invalid_json Corpo da requisição não é um JSON válido
400 no_fields_to_update Pelo menos um campo deve ser fornecido
401 unauthorized Usuário não possui permissões necessárias
404 tenant_configuration_not_found Configuração do tenant não encontrada

Suporte

Para dúvidas, sugestões ou suporte técnico, entre em contato: