IZII MDS - Orquestrador de Benefícios (REST) v2.0.0
API **RESTful** do Orquestrador de Benefícios da Izii - o *Hub de Integração
(Facade/Adapter)* que abstrai a comunicação com as operadoras de saúde e
odontológicas (Bradesco, SulAmérica, Unimed, Amil, etc.).
Esta especificação é a versão **100% REST** do contrato descrito no
*Manual de Orientação Técnica - API Orquestrador*. Em vez de um único endpoint
`POST` com um campo `movimento` (I/A/E/C), cada intenção de movimentação
cadastral é expressa pelo **verbo HTTP** e por um **recurso** próprio:
| Movimento (legado) | Verbo REST | Recurso |
|---------------------------|------------|-------------------------------------------|
| `I` Inclusão | `POST` | `/v1/beneficiarios` |
| `A` Alteração | `PATCH` | `/v1/beneficiarios/{cpf}` |
| `E` Exclusão | `DELETE` | `/v1/beneficiarios/{cpf}` |
| `C` Consulta (cadastro) | `GET` | `/v1/beneficiarios` · `/v1/beneficiarios/{cpf}` |
| Buscar movimentações | `GET` | `/v1/movimentacoes` · `/v1/movimentacoes/{id}` |
> Troca de Plano (`T`) e Reativação (`R`) ainda não estão disponíveis nesta
> API; serão publicadas quando o suporte estiver liberado.
## Autenticação
Envie `client_id` e `client_secret` em `POST /v1/auth/token` para obter um
**token JWT** (`access_token`, validade de 2 horas). O token deve ser enviado
no header `Authorization: Bearer <token>` em todos os endpoints de negócio
(sem token o gateway responde **401**).
## Roteamento por operadora
- A **operadora de destino** é informada no header `X-Cnpj-Provedor`
(CNPJ da operadora - ex. SulAmérica `01685053000156`), obrigatório em
todos os endpoints de dados.
- O inquilino (tenant) é resolvido do lado do servidor a partir da
credencial; não é enviado pelo consumidor.
## Padronização de respostas
Toda resposta de negócio chega com HTTP 200 (sucesso, em análise ou
rejeição): o desfecho está sempre no corpo, em `statusMovimentacao` e
`criticas`. Não derive sucesso/falha do código HTTP. Códigos não-200 indicam
erro de transporte/infra: **400** e **401** usam o schema `Erro`, **502** usa
`ErroDaApi`.
**Não encontrado também é HTTP 200**, não 404: a consulta que não localiza o
registro devolve `beneficiario: null` (e `protocolo`/`statusMovimentacao`
nulos, `criticas: []`). Trate ausência olhando o corpo, nunca o status.
**HTTP 502** significa que a operação não pôde ser concluída junto à
operadora. A leitura de `repetir` **depende do método**, e em escrita reenviar
pode duplicar a movimentação: ver a resposta `502` de cada operação.
`statusMovimentacao` observados: `"1"`/`"Em Processamento"` (aceite),
`"Aguardando Analise Operação"` (análise automática; pode vir com crítica
não bloqueante, ex. 2401: não é rejeição, não reenvie), `"Liberada"` e
`"Liberada com Critica"` (concluída, `carteirinha` emitida). Cada item de
`criticas` traz `bloqueante` (true/false/null), derivado do wrapper de
`validacoes`. O processamento é assíncrono (minutos a ~2-3 dias em
homologação): guarde o `protocolo` e acompanhe em
`GET /v1/movimentacoes/{protocolo}`.
## Credencial da empresa (`login`/`senha`)
Os corpos de escrita aceitam `login`/`senha`: é a credencial do **Portal Empresa
da empresa cuja vida está sendo movimentada**, e é com ela que a operadora
autentica a movimentação. Nunca são ecoados (mascarados `***` no `requestJson`).
**Em homologação são opcionais.** Omitidos, usa-se um usuário fixo do ambiente.
Preenchidos, valem apenas se forem **esse** usuário: qualquer outra credencial
(inclusive uma válida de produção) é recusada pela operadora com *"Parametros
obrigatórios de requisição indefinidos ou não enviados"*, após ~17s.
Campo só com espaços é tratado como **ausente** (cai no usuário fixo do
ambiente). Já uma credencial preenchida vai para a operadora **exatamente como
enviada**, sem aparar espaços: a senha é tratada como valor opaco.
**Em produção serão obrigatórios**, porque lá não há usuário fixo de ambiente:
cada movimentação precisa da credencial da sua empresa. Planeje o armazenamento
dessas credenciais desde já. Lá, escrita sem credencial é recusada de imediato
com **400**, em vez de seguir para a operadora e voltar ~17s depois com uma
mensagem que não menciona credencial.
## Tabelas de domínio (de-para)
Os valores codificados são **domínios da operadora**, servidos por endpoints
de consulta na API da SulAmérica (não são listas estáticas): motivos de
exclusão (`/motivos/exclusao` - ex. 1=A Pedido, 51=Demitido sem justa causa),
nacionalidades, bancos e outros. **`grauParentesco` é a exceção**, porque é a
origem mais comum de dependente cadastrado errado, então vai completo aqui:
| | | | |
|---|---|---|---|
| **0** Titular | **1** Cônjuge/Esposo(a) | **2** Companheiro(a) | **3** Filho(a) |
| **4** Tutelado/Enteado | **5** Pai/Mãe | **6** Sogro(a) | **7** Genro/Nora |
| **8** Neto(a) | **9** Outros | **10** Irmão/Irmã | **11** Invalidez |
| **51** Agregado | | | |
Repare que **filho é `3`**, não `1`: `1` é cônjuge. Demais domínios:
nacionalidades (`/nacionalidades` - 114=Brasileira), bancos (`/bancos` -
código Febraban de 3 dígitos), locais e planos válidos POR EMPRESA
(`/estipulantes/{codEmpresa}/locais|planos`). Valores fixos conhecidos:
`sexo` M/F; `estadoCivil` S/C/V/D/O; `tipoConta` 1=Corrente, 2=Poupança.
As tabelas completas podem ser solicitadas pelo canal de suporte.
## Grupo familiar
**O lote é tudo ou nada, e isso vem do provedor.** Com uma vida recusada, NENHUMA
entra, nem as corretas: medido em 05/10/2026 com CPF de dígito inválido (A005) e com
grau inexistente (A1019) na segunda vida de três, e nas duas vezes as três ficaram
fora, confirmado por consulta depois.
A regra **é da operadora**, não desta API nem do Orquestrador. Medido interceptando o
hop: o Orquestrador envia as três vidas num único POST para o endpoint de inclusões
da SulAmérica, que responde 400 "Erro na movimentação" com uma `validation` apontando
só a vida ruim, e nenhuma das três é cadastrada. Chamando o Orquestrador direto, sem
esta fachada no caminho, o resultado é o mesmo. Ninguém no meio decide isso.
Na prática: `resultados` vem vazio e `validacoes` traz um item por vida recusada,
nomeando o beneficiário. Isso é bom para família (não existe meia família
cadastrada), mas o reenvio é do lote inteiro, não da vida que falhou.
**Mande a família inteira num array, titular na frente.** Não existe campo de
dependentes dentro do corpo: cada vida é um registro. Enviando as três vidas numa
requisição, as três entram sem crítica nenhuma, com a mesma `matriculaProvedor` e um
`sequencial` por vida: quatro repetições em 05/10/2026, quatro aceites. O array não
espera a propagação, que é o problema do envio um a um.
Enviando **uma por vez**, o dependente é recusado logo após a inclusão do titular e
aceito algum tempo depois, com o payload idêntico. Três famílias medidas em
05/10/2026, tentando a cada 22 segundos, deram a mesma sequência:
| t desde a inclusão do titular | `statusMovimentacao` | dependente |
|---|---|---|
| 0s | Em Processamento | **A015** |
| 22s | **Liberada** | **A015** |
| 44s a 50s | Liberada | **A1083** |
| 44s a 72s | Liberada | aceito |
Ou seja: `Liberada` **não significa que o dependente já pode entrar**, e as duas
críticas são estágios da mesma espera, não problemas diferentes. A A015 é a mais
cruel porque a mensagem acusa a matrícula, que está correta.
**Não dimensione retry por esses números.** Nas três famílias acima a espera ficou
entre 44 e 72 segundos, mas num quarto titular, igualmente `Liberada` e já com
`matriculaFamilia` atribuída, o dependente continuava recebendo A015 **mais de dez
minutos depois**. Trate A015 e A1083 na inclusão de dependente como "ainda não,
tente de novo", sem prazo. Ou mande a família junta e não dependa disso.
## Críticas conhecidas (observadas em homologação SulAmérica)
| Código | Mensagem/Significado | Ação |
|--------|----------------------|------|
| A041 | CPF já cadastrado | Use outro CPF ou trate como duplicidade |
| A015 | Matrícula inconsistente. Observadas duas mensagens: matrícula já usada no contrato, e **matrícula do beneficiário diferente da do titular** | **A mensagem engana.** Medimos em 05/10/2026: com a matrícula CERTA, enviada igual à do titular, a inclusão do dependente foi recusada com esta crítica logo após o titular ser incluído, e a MESMA requisição foi aceita minutos depois, sem mudar um byte. O que varia entre a recusa e o aceite é o tempo decorrido desde a inclusão do titular, e esse intervalo não é fixo. O valor da matrícula não é a causa. Ver "Grupo familiar" abaixo |
| A1002 | Matrícula inválida! São 8 Números | `matriculaFuncionario` passou de 8 dígitos. Medido: 7 e 8 dígitos não produzem esta crítica, 9, 10 e 12 produzem. Acontece ao usar `matriculaFamilia`, que tem 9. Abaixo de 8 o preenchimento com zeros à esquerda é indiferente, a operadora normaliza |
| A1032 | Grau de parentesco exige documento comprobatório (companheiro, pais, agregados, enteados, outros) | Graus `3` a `6`. Cônjuge é `grauParentesco: "1"` e filho(a) é `"2"`, os únicos que entram sozinhos |
| A1019 | Grau Parentesco inválido para seguro tipo saúde | Graus `7` a `9` não existem para saúde |
| A1081 | Já existe um titular ativo para essa matrícula | `grauParentesco: "0"` numa matrícula que já tem titular. Para somar vidas à família, use `1` ou `2` |
| A1050 | PisPasep inválido | O dígito verificador é conferido |
| A034 / A035 | Data de Admissão obrigatória / inválida | `dataAdmissao` em `YYYY-MM-DD`, **também no dependente** |
| A1083 | Inclusão não permitida. Titular não encontrado ou não existe | Aparece na mesma situação da A015. `statusMovimentacao: Liberada` **não basta**: medimos A1083 com o titular já liberado e aceitação da mesma requisição 4 minutos depois. As duas críticas aparecem na mesma espera, em momentos diferentes |
| A7008 | Plano inválido | O plano vale **por empresa**; use um da lista de planos daquele estipulante |
| A1006 | Nome abreviado deve ter até 32 caracteres | Reduza `nomeAbreviado` |
| A1034 | Nome completo com caracteres inválidos | Envie `nome` sem acentos |
| A1046 | Nome abreviado com caracteres inválidos | Envie `nomeAbreviado` sem acentos |
| A1080 | Sugestão de nome abreviado | Acompanha A1046 e traz um valor aceito |
| A02003 | Matrícula preenchimento obrigatório (alteração) | Informe a matrícula do beneficiário |
| A02011 | Beneficiário não encontrado ou não existe (escrita) | Confira a `matriculaEmpresa`: é a `matriculaProvedor` da inclusão (na consulta vem em `matriculaFamilia`), não o protocolo. Ocorre também quando a inclusão ainda não foi liberada |
| A02035 | Beneficiário já está excluído (a crítica informa a data) | Exclusão já registrada; não reenvie |
| A02040 | Código do produtor sem permissão para movimentar a empresa | `produto.subContrato`/`codigoRDP` não correspondem à empresa da vida; use os mesmos da inclusão |
| M21001 | Data de exclusão inválida | Use a data de corte permitida (a crítica lista as datas) |
| M30001 | Arquivo obrigatório para empresa com faturamento por faixa etária (alteração) | A alteração dessa empresa exige um anexo que o contrato atual não transporta; trate como não suportada e acione o suporte |
| 2401 | Validar a elegibilidade e a conformidade dos dados cadastrais (Automatica) | Não bloqueante; acompanha a análise automática e NÃO impede a liberação |
| 212/79/329/334 | Movimentação encaminhada para análise interna | Não bloqueante; aguarde o processamento |
Abrir