Documentação da API Axenya
A API pública da Axenya permite que a equipe de TI de uma empresa opere toda a rotina de RH de benefícios de forma programática — sem planilhas, sem portal, sem trabalho manual. Inclusões, exclusões, trocas de plano e alterações de cadastro entram por chamadas HTTP; o envio de arquivos de compliance segue o mesmo caminho.
O v1 é inbound (ingestão): sua empresa alimenta dados na Axenya. Esta documentação mostra como conectar seus sistemas de RH (ERP, folha, sistema de admissão) aos fluxos da Axenya e automatizar a operação ponta a ponta.
Como funciona
A axenya-public-api é uma camada pública de ingestão
que fica na frente dos backends internos da Axenya (HR Portal e
Landing Zone). Toda chamada autenticada por API key passa por cinco
etapas no servidor:
TLS + API Key
Sua empresa ───────────────────────────► axenya-public-api
(sistema de RH) │ 1. autentica a API key (hash em repouso)
│ 2. resolve tenant + scopes da key
│ 3. valida o JSON contra o schema gerado
│ 4. cria uma "submission" (recibo) — async
│ 5. chama o backend interno injetando
▼ o tenant resolvido
┌───────────────┼───────────────────────────┐
▼ │ ▼
hr-portal-api ◄───────┘ landing-zone backend
(movimentação de vidas) (file-types / signed URL GCS)
Tenant pela key
A empresa nunca vai no payload — é derivada da API key no servidor. Um cliente jamais escolhe o tenant.
Escrita assíncrona
Validação não é instantânea (matching de vida, janelas,
antivírus). Toda escrita responde 202 com um
recibo.
JSON canônico
Você envia JSON limpo. O schema é gerado a partir da definição do backend — sem planilha, sem mapeamento manual.
O isolamento entre empresas é a garantia número 1 da API. A
identidade da sua empresa (tenant) é sempre resolvida a partir da
API key — nunca de um campo no corpo da requisição. Não existe
unitId no payload. A única exceção são as
keys de grupo (abaixo): por abrangerem várias
unidades, a unidade-alvo é informada e validada contra o grupo.
Grupos e unidades — visão consolidada
Um grupo reúne várias unidades (tenants) sob a mesma gestão de TI. Além da key por unidade, a Axenya emite keys de grupo, que dão visão consolidada sobre todas as unidades do grupo — sem precisar orquestrar N keys manualmente.
| Tipo de key | Consultas (GET) | Escritas (movimentações) |
|---|---|---|
| Key de unidade (tenant) | Apenas a própria unidade. | Unidade resolvida pela key; sem unitId no payload. |
| Key de grupo | Todas as unidades do grupo, com unit em cada item retornado. |
A unidade-alvo é informada via unitId e validada como membro do grupo antes de qualquer escrita. |
Uma key de grupo nunca alcança unidades fora do seu grupo, e cada movimentação continua atribuída a uma única unidade-alvo. A consolidação é de visão — o isolamento entre grupos permanece a garantia número 1.
Primeiros passos
Em menos de cinco minutos você faz a primeira consulta e a primeira movimentação. Você só precisa de uma API key do seu tenant (fornecida pela Axenya).
-
Configure o ambiente
Exporte a URL base e sua API key. A empresa é resolvida pela key
— não precisa de mais nada.
bash
export AXENYA_API="https://api.axenya.com/v1" export AXENYA_KEY="axk_live_3f8a...e21" # resolve sua empresa no servidor -
Encontre uma vida pelo CPF
Toda operação de RH normalmente começa achando a vida. O CPF
(
document) é a chave natural de matching.bashcurl -sS "$AXENYA_API/beneficiaries?document=39053344705" \ -H "Authorization: Bearer $AXENYA_KEY"json · 200{ "data": [ { "id": "ben_01HZX...", "name": "Maria Silva", "document": "390.533.447-05", "subscriberType": "HOLDER", "status": "ACTIVE" } ], "meta": { "totalItems": 1 } } -
Envie sua primeira movimentação
Escritas exigem o header
Idempotency-Keye respondem202com um recibo. Acompanhe o processamento depois.bashcurl -sS -X POST "$AXENYA_API/movements" \ -H "Authorization: Bearer $AXENYA_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: adm-2026-0001-maria" \ -d '{ "movementType": "INSERT", "effectiveDate": "2026-07-01", "policyId": "pol_saude_123", "planId": "plan_premium", "beneficiary": { "subscriberType": "HOLDER", "name": "Maria Silva", "document": "39053344705", "birthDate": "1990-04-12", "gender": "FEMALE" } }' -
Acompanhe o recibo
Use o
submissionIdretornado para checar o status — ou receba um webhook quando processar.bashcurl -sS "$AXENYA_API/movements/mov_01J2K..." \ -H "Authorization: Bearer $AXENYA_KEY"
Autenticação
A autenticação é máquina-a-máquina (M2M) por
API keys por tenant. Cada chamada leva o header
Authorization: Bearer <sua-key>.
Formato da key
As keys têm prefixo de ambiente e são exibidas uma única vez no momento da criação. Guarde-as em um cofre de segredos (Secret Manager, Vault) — a Axenya armazena apenas o hash.
| Prefixo | Ambiente | Uso |
|---|---|---|
axk_live_… |
Produção | Movimentações reais que afetam vidas e apólices. |
axk_test_… |
Teste | Integração e validação sem efeitos no cadastro real. |
Uma key pode ser de unidade (um único tenant) ou de grupo (várias unidades do grupo, com visão consolidada). O tipo é definido na emissão da key, não no payload.
Scopes
Cada key carrega um conjunto de scopes. Use o princípio do menor privilégio.
| Scope | Permite |
|---|---|
movements:write | Submeter movimentações de beneficiários. |
files:write | Enviar arquivos para a Landing Zone. |
submissions:read | Consultar vidas, apólices, templates e status de recibos. |
Os scopes acima são permissões
máquina-a-máquina da API. Os perfis humanos
(médico, RH, analista) e o login via SSO (Entra ID)
pertencem ao portal da Axenya e são documentados
à parte — não se confundem com os scopes de uma key.
Boas práticas de segurança
- Rotação sem downtime: até 2 keys ativas por tenant. Crie a nova, migre, revogue a antiga.
- Revogação imediata e
expiresAtpor key;lastUsedAtpara auditoria. - TLS 1.2+ obrigatório; IP allowlist opcional por key.
- Rate limit e quota aplicados por key.
- Nunca registre a key em logs, URLs ou repositórios.
Revogue imediatamente no painel (ou peça à Axenya) e gere uma nova. Como o tenant é vinculado à key, uma key comprometida só afeta a própria empresa — mas revogue mesmo assim.
Modelo de operação de RH
Não existe um endpoint por tarefa de RH. Toda a operação se reduz a 4 primitivas de movimentação, combinadas com consultas (GET) para encontrar a vida e o plano certos.
Inclusão
Admissão de titular ou inclusão de dependente em uma apólice.
Exclusão
Desligamento de titular ou cancelamento de dependente.
Alteração de plano
Troca de plano/produto de uma vida (de → para).
Alteração de cadastro
Endereço, centro de custo e demais campos cadastrais.
A chave de matching é sempre CPF (document) +
apólice — sua empresa não conhece o identificador interno
(bid) da Axenya, e não precisa. Os campos válidos de
cada primitiva vêm do schema gerado daquele
movementType.
Saúde, odontológico e vida são apólices distintas
(policyId) sobre a mesma vida. Não
existe API separada por benefício: as 4 primitivas operam qualquer
linha de benefício, e uma admissão pode aderir a várias apólices
na mesma rotina — uma movimentação por apólice, todas com o mesmo
document. A operadora de cada apólice é transparente
para você (o schema é o mesmo, provider-agnostic).
Termos negociados por acordo/convenção entram como parâmetros da movimentação, não exigem endpoint próprio:
-
coparticipationna adesão/troca de plano — define o rateio de custo do beneficiário (ex.: integral, parcial ou percentual). -
deactivationDelayDaysno desligamento — dias de permanência após a data efetiva antes da desativação valer.
Ambos são opcionais e validados pelo schema do
movementType.
Os 7 cenários de RH
Estes são os fluxos do dia a dia de um time de benefícios. Cada um é uma combinação das 4 primitivas com as consultas necessárias.
| # | Cenário | Primitiva | Consultas antes |
|---|---|---|---|
| 1 | Admissão + adesão | INSERT (titular) | /policies |
| 2 | Inclusão de dependente | INSERT (dependente) | /beneficiaries → /dependents |
| 3 | Alteração de endereço | REGISTRATION_UPDATE | /beneficiaries/{id} |
| 4 | Mudança de centro de custo | REGISTRATION_UPDATE | /beneficiaries/{id} |
| 5 | Troca de plano | UPDATE | /contract-history + /policies |
| 6 | Cancelamento de dependente | DELETE (dependente) | /dependents |
| 7 | Desligamento | DELETE (titular) | /beneficiaries → /dependents |
Admissão com adesão ao plano
INSERT · titularCria a vida do titular já com o plano. Consulte /policies antes para obter o policyId e o planId. Para aderir a mais de um benefício (saúde, odonto, vida), repita a movimentação por apólice. coparticipation é opcional.
curl -sS -X POST "$AXENYA_API/movements" \
-H "Authorization: Bearer $AXENYA_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: adm-2026-0001-maria" \
-d '{
"movementType": "INSERT",
"effectiveDate": "2026-07-01",
"policyId": "pol_saude_123",
"planId": "plan_premium",
"coparticipation": { "mode": "PARCIAL" },
"beneficiary": {
"subscriberType": "HOLDER",
"name": "Maria Silva", "document": "39053344705",
"enrollmentNumber": "0012345", "birthDate": "1990-04-12",
"admissionDate": "2026-07-01", "gender": "FEMALE",
"maritalStatus": "SOLTEIRO", "phone": "+5511999998888"
}
}'
Inclusão de dependente
INSERT · dependenteReferencia o titular pelo CPF em holder.document e informa o dependencyRelation.
curl -sS -X POST "$AXENYA_API/movements" \
-H "Authorization: Bearer $AXENYA_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: dep-2026-0001-joao" \
-d '{
"movementType": "INSERT",
"effectiveDate": "2026-07-01",
"policyId": "pol_saude_123",
"beneficiary": {
"subscriberType": "DEPENDENT",
"holder": { "document": "39053344705" },
"dependencyRelation": "CONJUGE",
"name": "João Silva", "document": "12345678909",
"birthDate": "1989-02-03", "gender": "MALE"
}
}'
Alteração de endereço
REGISTRATION_UPDATEOs campos de registration são definidos pelo schema gerado da versão — não é um objeto livre.
curl -sS -X POST "$AXENYA_API/movements" \
-H "Authorization: Bearer $AXENYA_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: end-2026-0001-maria" \
-d '{
"movementType": "REGISTRATION_UPDATE",
"effectiveDate": "2026-07-01",
"beneficiary": { "document": "39053344705" },
"registration": {
"address": {
"zipCode": "01310100", "street": "Av. Paulista", "number": "1000",
"complement": "Conj. 51", "neighborhood": "Bela Vista",
"city": "São Paulo", "state": "SP"
}
}
}'
Mudança de centro de custo
REGISTRATION_UPDATEMesmo tipo de movimentação, outro campo de cadastro confirmado pela definição do template.
curl -sS -X POST "$AXENYA_API/movements" \
-H "Authorization: Bearer $AXENYA_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: cc-2026-0001-maria" \
-d '{
"movementType": "REGISTRATION_UPDATE",
"effectiveDate": "2026-07-01",
"beneficiary": { "document": "39053344705" },
"registration": { "costCenter": "CC-OPS-2026" }
}'
Troca de plano
UPDATEMapeia 1:1 com UPDATE. Informe fromPlanId e toPlanId.
curl -sS -X POST "$AXENYA_API/movements" \
-H "Authorization: Bearer $AXENYA_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: plan-2026-0001-maria" \
-d '{
"movementType": "UPDATE",
"effectiveDate": "2026-08-01",
"policyId": "pol_saude_123",
"beneficiary": { "document": "39053344705" },
"fromPlanId": "plan_basic", "toPlanId": "plan_premium"
}'
Cancelamento de dependente
DELETE · dependenteExclui apenas a vida do dependente. Identifique-o pelo próprio CPF.
curl -sS -X POST "$AXENYA_API/movements" \
-H "Authorization: Bearer $AXENYA_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: del-dep-2026-0001-joao" \
-d '{
"movementType": "DELETE",
"effectiveDate": "2026-07-31",
"beneficiary": { "document": "12345678909" },
"reason": "EXCLUSAO_DEPENDENTE"
}'
Desligamento do titular
DELETE · titularUse cascadeDependents para excluir também os dependentes vinculados e deactivationDelayDays para honrar a permanência prevista em acordo/convenção (desativar N dias após a data efetiva).
curl -sS -X POST "$AXENYA_API/movements" \
-H "Authorization: Bearer $AXENYA_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: deslig-2026-0001-maria" \
-d '{
"movementType": "DELETE",
"effectiveDate": "2026-07-31",
"beneficiary": { "document": "39053344705" },
"reason": "DESLIGAMENTO",
"deactivationDelayDays": 30,
"cascadeDependents": true
}'
No desligamento do titular, cascadeDependents: true
exclui também os dependentes vinculados na mesma data;
false mantém os dependentes ativos.
deactivationDelayDays programa a desativação para
N dias após a effectiveDate (ex.:
30 = mais 30 dias de cobertura). Sem o campo, a
desativação é imediata na data informada.
Sync de folha de pagamento (reconciliação)
Tudo que vimos até aqui é imperativo: você diz a movimentação ("exclua o CPF X"). A folha de pagamento é o oposto — é declarativa. Você envia o retrato de quem deve estar ativo e a Axenya calcula as movimentações pela diferença contra o estado atual. É o mesmo padrão de reconciliação por estado desejado do Kubernetes: você não manda o delta, manda o alvo, e o motor deriva o delta.
Folha (estado desejado) ─┐
├─► motor de diff ─► plano de reconciliação ─► (aprova) ─► /movements
Estado atual na Axenya ─┘ (desired vs current) (preview das mov.) (pipeline existente)
Ela alimenta o mesmo pipeline de movimentações, só que de forma derivada. As 4 primitivas continuam sendo o destino — a folha apenas as calcula para você.
O motor de diff → as 4 primitivas
A diferença entre folha e estado atual (chave = CPF) gera exatamente as primitivas que já existem:
| Situação (chave = CPF) | Movimentação derivada |
|---|---|
| Na folha, não existe na Axenya | INSERT (admissão/adesão) |
| Existe na Axenya, ausente na folha | DELETE (desligamento) ⚠️ |
| Em ambos, plano diferente | UPDATE (troca de plano) |
| Em ambos, cadastro diferente | REGISTRATION_UPDATE |
| Em ambos, idêntico | no-op (não gera nada) |
A armadilha crítica: exclusão por omissão
O quadrante perigoso é "ausente na folha → DELETE". Uma
folha truncada, um arquivo parcial ou um erro de export poderiam
desligar gente em massa. Sem proteção, isso é um
incidente. Por isso os controles abaixo são obrigatórios.
mode: full | partial— o controle mais importante. Emfull, a folha é o retrato completo e a omissão significa exclusão; empartial(delta), a omissão não faz nada.- Escopo = titulares. Folha lista funcionários, não dependentes. Nunca inferir exclusão de dependente por ausência — senão toda folha sem dependentes zeraria os dependentes.
- Guardrails por limiar: se as exclusões derivadas passarem de X% da base (ou N absoluto), o plano é bloqueado e exige confirmação explícita.
- Dry-run obrigatório: sempre gerar o plano (preview) antes de aplicar — ao menos nas primeiras execuções.
- Idempotência natural: reenviar a mesma folha gera diff vazio (nada acontece).
Quais dos 7 cenários derivam da folha?
Honestidade importante: depende das colunas que a folha carrega.
| # | Cenário | Derivável da folha? |
|---|---|---|
| 1 | Admissão + adesão | ✅ Sim (admissão); adesão só se a folha trouxer o plano |
| 3 | Alteração de endereço | ✅ Se a folha trouxer endereço |
| 4 | Mudança de centro de custo | ✅ Forte — folha quase sempre tem |
| 5 | Troca de plano | ⚠️ Só se a folha trouxer a elegibilidade/plano |
| 7 | Desligamento | ✅ Sim (ausência em mode: full ou data explícita) |
| 2 | Inclusão de dependente | ❌ Só se for censo com dependentes |
| 6 | Cancelamento de dependente | ❌ Idem — e nunca por omissão |
Em resumo: a folha resolve muito bem admissão, desligamento, centro de custo e cadastro de titulares; plano e dependentes dependem do conteúdo do arquivo.
Fluxo: preview → apply
Dois passos, pela segurança. Primeiro você envia a folha e revisa o plano derivado; só então aplica.
-
Abra o sync e envie a folha
Mesmo padrão de signed URL — o arquivo não passa pela API.
bash
curl -sS -X POST "$AXENYA_API/payroll-syncs:initiate" \ -H "Authorization: Bearer $AXENYA_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: folha-2026-07" \ -d '{ "referenceMonth": "2026-07", "effectiveDate": "2026-07-01", "mode": "full", "scope": "HOLDERS" }' # -> { "syncId": "pyr_01J...", "uploadUrl": "https://storage.googleapis.com/...", # "requiredHeaders": { ... } }Depois, faça o
PUTdo arquivo nauploadUrl(como em qualquer fluxo de arquivo). -
Consulte o plano derivado (dry-run)
Quando
status = planned, o sync devolve o plano completo comsummaryeguardrails.bashcurl -sS "$AXENYA_API/payroll-syncs/pyr_01J..." \ -H "Authorization: Bearer $AXENYA_KEY"json · 200{ "syncId": "pyr_01J...", "status": "planned", "mode": "full", "scope": "HOLDERS", "summary": { "inserts": 12, "deletes": 3, "planChanges": 5, "registrationUpdates": 8, "noops": 940, "unmatched": 2 }, "guardrails": { "deleteRatio": 0.003, "blocked": false }, "movements": [ { "movementType": "INSERT", "beneficiary": { "document": "111...", "name": "..." }, "source": { "row": 14 } }, { "movementType": "DELETE", "beneficiary": { "document": "222...", "name": "..." }, "reason": "ABSENT_IN_PAYROLL" }, { "movementType": "UPDATE", "beneficiary": { "document": "333..." }, "fromPlanId": "basic", "toPlanId": "premium" } ], "unmatched": [ { "row": 87, "document": "999...", "issue": "CPF inválido" } ] } -
Aplique o plano
Depois de revisar (ou automaticamente se os guardrails estiverem ok). Cada movimentação vira um
submissionrastreável.bashcurl -sS -X POST "$AXENYA_API/payroll-syncs/pyr_01J...:apply" \ -H "Authorization: Bearer $AXENYA_KEY" \ -H "Content-Type: application/json" \ -d '{ "confirm": true, "acknowledgeDeletes": 3 }' # -> status: applying -> completedO campo
acknowledgeDeletesprecisa bater com o número de exclusões do plano — uma trava extra contra desligamento acidental em massa.
Endpoints
Como a folha é mapeada
Aqui aparece o único ponto que exige mais do que o template canônico: toda folha/ERP exporta diferente. Duas saídas:
Template canônico de folha
Cliente preenche uma planilha padrão, derivada da mesma máquina de definição dos templates. Mais simples — recomendado para começar.
Perfil de mapeamento por tenant
Colunas nativas do ERP do cliente → canônicas. Melhor DX, mais setup. Fica para uma fase 2.
Classificações que exigem cuidado
- CPF novo pode ser re-admissão de alguém
INACTIVE→ reativação, não inclusão nova (checar status atual). - CPF ausente pode ser afastamento, não desligamento → por isso
mode+ limiares. - Mesmo CPF com nome diferente → correção cadastral, não pessoa nova.
Recibos & status
Como a ingestão é assíncrona, toda escrita responde
202 Accepted com um objeto submission — o
recibo. Guarde o id para acompanhar.
{
"submission": {
"id": "mov_01J2K...",
"movementType": "INSERT",
"schemaVersion": "2026-06-01",
"status": "received",
"createdAt": "2026-06-04T13:20:00Z"
}
}
Ciclo de vida do status
| Status | Significado |
|---|---|
received | Recibo criado, na fila para processar. |
validating | Validando contra schema e regras de negócio. |
processing | Backend aplicando a movimentação. |
completed | Tudo aceito. |
partially_completed | Parte aceita, parte rejeitada (ver result.errors). |
rejected | Nada aplicado; veja os erros. |
Consultar o status
curl -sS "$AXENYA_API/movements/mov_01J2K..." \
-H "Authorization: Bearer $AXENYA_KEY"
{
"id": "mov_01J2K...",
"status": "rejected",
"schemaVersion": "2026-06-01",
"result": {
"accepted": 0,
"rejected": 1,
"errors": [
{
"row": 1,
"field": "beneficiary.document",
"code": "BENEFICIARY_NOT_FOUND",
"message": "Nenhuma vida ativa com este CPF na apólice."
}
]
}
}
O backend valida por coluna/linha (modelo de planilha). Como o
transform é determinístico, a camada pública reverte o erro para
o campo JSON que você enviou (ex.: cpf →
beneficiary.document) antes de devolver.
Webhooks
Em vez de fazer polling no status, registre um endpoint para receber eventos quando uma movimentação for processada. Os webhooks são assinados via HMAC e têm retry com backoff.
| Evento | Quando dispara |
|---|---|
movement.processed | Movimentação concluída (total ou parcial). |
movement.failed | Movimentação rejeitada. |
file.validated | Arquivo da Landing Zone validado. |
Verificando a assinatura
Cada entrega traz um header com a assinatura HMAC-SHA256 do corpo. Recompute com seu segredo de webhook e compare em tempo constante antes de confiar no payload.
# pseudo-verificação
expected=$(printf '%s' "$RAW_BODY" \
| openssl dgst -sha256 -hmac "$WEBHOOK_SECRET" -binary \
| base64)
# compare 'expected' com o header X-Axenya-Signature
Convenções
Regras transversais que valem para toda a API.
| Tema | Convenção |
|---|---|
| Base URL | https://api.axenya.com/v1 |
| Versionamento | Prefixo /v1 próprio, independente do versionamento interno. |
| Autenticação | Authorization: Bearer <key> em toda chamada. |
| Tenant | Derivado da key. Nunca no payload. |
| Idempotência | Header Idempotency-Key obrigatório em toda escrita. |
| Erros | RFC 7807 (application/problem+json) + errors[] por item. |
| Schema | schemaVersion ecoado no recibo; mudança aditiva não quebra. |
| Auditoria | Toda chamada atribuída a keyId + tenant. |
Idempotência
Reenviar uma requisição com a mesma Idempotency-Key
retorna o mesmo recibo, sem duplicar a movimentação. Use uma chave
estável e única por operação (ex.:
adm-2026-0001-maria). Isso torna seus retries seguros.
Consultas (GET)
Endpoints de leitura para encontrar vidas, planos e templates antes de movimentar. Requerem o scope submissions:read.
?format=xlsx gera a planilha)
Movimentações (HR Portal)
Escrita de movimentações de beneficiários. Requer o scope movements:write (exceto a consulta de status).
Tipos de movimentação
| movementType | Descrição |
|---|---|
INSERT | Inclusão (titular ou dependente). |
DELETE | Exclusão (titular ou dependente). |
UPDATE | Alteração de plano. |
REGISTRATION_UPDATE | Alteração de cadastro. |
Alternativa por arquivo
Para volumes grandes, use o fluxo de upload nativo do backend. O template canônico vem do mesmo schema (veja Templates).
-
Peça a URL de upload
bash
curl -sS -X POST "$AXENYA_API/movements:initiate" \ -H "Authorization: Bearer $AXENYA_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: file-2026-0001" \ -d '{ "movementType": "INSERT", "contentType": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" }' -
Envie o arquivo direto ao GCS (não passa pela API)
bash
curl -sS -X PUT "<uploadUrl>" \ -H "Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" \ -H "x-goog-meta-movementtype: INSERT" \ --upload-file inclusoes-julho.xlsx - Acompanhe com
GET /movements/{submissionId}.
Arquivos (Landing Zone)
Submissão de arquivos de compliance por fileType + período. Requer files:write.
O fluxo é o mesmo padrão de signed URL: você pede a URL, envia o
arquivo direto ao storage e confirma. A validação (incluindo
antivírus) acontece de forma assíncrona — acompanhe pelo status ou
pelo webhook file.validated.
Templates & schema
O cliente B2B nunca mantém um template à mão. O
hr-portal-api expõe a definição estruturada de cada
movementType (colunas, tipos, obrigatórios, enums,
versão); a camada pública consome e gera o JSON Schema
canônico. Coluna nova no backend aparece sozinha no schema
— sem drift, sem variante por operadora.
hr-portal-api axenya-public-api cliente
───────────── ───────────────── ───────
definição estruturada ─(fetch+cache)─► gera JSON Schema ─(serve)─► GET /movement-templates/{type}
do template (por tipo) canônico + versão
│
POST /movements (JSON) ─────────────────────┤ valida o JSON contra o schema
│ transforma JSON → colunas/linhas
upload existente ◄────────────────────┤ alimenta o fluxo de upload
valida (autoritativo) │
failed-rows (coluna/linha) ──────────►│ reverte p/ o caminho JSON e devolve no recibo
Uma definição, três usos
A mesma definição alimenta:
- O JSON Schema da API (validação e DX);
- O XLSX canônico (
?format=xlsx, para o modo arquivo); - A planilha em branco da própria UI da Axenya.
Obtendo o schema de um tipo
# JSON Schema canônico
curl -sS "$AXENYA_API/movement-templates/INSERT" \
-H "Authorization: Bearer $AXENYA_KEY"
# Planilha XLSX equivalente
curl -sS "$AXENYA_API/movement-templates/INSERT?format=xlsx" \
-H "Authorization: Bearer $AXENYA_KEY" --output insert.xlsx
Definição estruturada (contrato interno)
Exemplo do que o backend devolve por tipo — fonte da verdade de colunas, tipos, obrigatórios e enums:
{
"movementType": "INSERT",
"version": "2026-06-01",
"columns": [
{ "key": "cpf", "type": "string", "required": true, "pattern": "^\\d{11}$" },
{ "key": "nome", "type": "string", "required": true },
{ "key": "dataNascimento", "type": "date", "required": true },
{ "key": "dataAdmissao", "type": "date", "required": false },
{ "key": "sexo", "type": "enum", "required": true, "enum": ["M", "F"] },
{ "key": "tipoBeneficiario", "type": "enum", "required": true, "enum": ["TITULAR", "DEPENDENTE"] },
{ "key": "cpfTitular", "type": "string", "required": false },
{ "key": "grauParentesco", "type": "enum", "required": false, "enum": ["CONJUGE", "FILHO", "..."] }
]
}
Regras de geração
keydo backend →camelCaseno JSON, com um dicionário enxuto de apelidos (ex.:dataNascimento → birthDate).- Agrupamento por convenção:
cpf/nome/… → beneficiary.*,cep/rua/… → registration.address.*. required/type/enum/patternviram restrições do JSON Schema.versionpropaga para o schema e é ecoada comoschemaVersionno recibo.
A camada pública cacheia a definição por version
(refetch por TTL ou webhook). Você pode pinar uma versão; mudanças
aditivas não quebram, rename/remoção geram nova versão.
Erros
Erros de protocolo seguem RFC 7807
(application/problem+json). Erros por item de uma
movimentação vêm em result.errors[] no recibo.
| HTTP | Significado |
|---|---|
202 | Escrita aceita — recibo criado (async). |
400 | JSON inválido ou falha de schema. |
401 | API key ausente ou inválida. |
403 | Scope insuficiente para a operação. |
404 | Recurso (submission, vida) não encontrado. |
409 | Conflito de idempotência (mesma key, payload diferente). |
422 | Regra de negócio violada. |
429 | Rate limit/quota da key excedido. |
{
"type": "https://docs.axenya.com/errors/insufficient-scope",
"title": "Scope insuficiente",
"status": 403,
"detail": "A API key não possui o scope movements:write.",
"instance": "/v1/movements"
}
Glossário
| Termo | Definição |
|---|---|
| Tenant | Sua empresa. Resolvido a partir da API key, nunca do payload. |
| Beneficiário / vida | Pessoa coberta — titular (HOLDER) ou dependente (DEPENDENT). |
| Movimentação | Operação de RH expressa em uma das 4 primitivas. |
| Submission | Recibo de uma escrita assíncrona, com id e status. |
| Apólice (policy) | Contrato com a operadora ao qual a vida é vinculada. |
| Document | CPF — a chave natural de matching de uma vida. |
| Landing Zone | Domínio de envio de arquivos de compliance. |
| Grupo | Conjunto de unidades (tenants) com visão consolidada via key de grupo. |
| Unidade | Empresa/tenant individual dentro de um grupo. Resolvida pela key ou informada via unitId por uma key de grupo. |
| Coparticipação | Rateio de custo do beneficiário no plano (coparticipation). |
| Permanência pós-desligamento | Dias de cobertura após a data efetiva (deactivationDelayDays). |
| schemaVersion | Versão da definição de template ecoada no recibo. |