---
title: "Cadastra vários usuários numa requisição"
method: POST
path: "/v1/users/enrollments"
tags: ["Users"]
---

# Cadastra vários usuários numa requisição

`POST /v1/users/enrollments`

## Request

- Base URL: `https://api.signdocs.com.br`
- URL: `https://api.signdocs.com.br/v1/users/enrollments`
- Auth: HTTP bearer

Cadastra até **25** usuários de uma vez, para popular a base no dia da
virada sem disparar um `PUT` por funcionário.

**Sucesso parcial é o comportamento pretendido.** Uma foto ruim entre
vinte e cinco não pode reprovar as outras vinte e quatro, então cada
linha reporta o próprio resultado e a resposta é **200 mesmo quando há
linhas reprovadas**. Leia `results`, não o código HTTP — quem trata só o
status considera aprovado um lote em que metade falhou.

`userExternalId` repetido no mesmo lote é **400**: as linhas correriam
sobre a mesma chave e a versão final ficaria imprevisível.

**Limite real é o tamanho do corpo, não as 25 linhas.** A invocação
síncrona da Lambda corta em ~6 MB, e a imagem em base64 cresce um terço.
Medido em HML: 25 fotos de 53 KB = 1,82 MB, aprovado em 5 s; 8 fotos de
536 KB = 5,72 MB passa, 9 = 6,44 MB devolve **413**. Para usar as 25
vagas, mantenha cada foto abaixo de ~175 KB — 640×640 com qualidade 82
dá 53 KB e ainda detecta rosto com 99,99 de confiança.

Cadastrar **não** consome cota: nem de documento, nem de biometria. A
cota é debitada quando a assinatura acontece, não quando o funcionário
entra na base.

## Request body

- object
  - `dryRun` boolean: Inspeciona sem gravar. Cada linha é avaliada e devolvida com métricas de qualidade, e **nada é persistido** — nenhuma imagem vai para o S3, nenhum registro para o DynamoDB, e o prazo de retenção de 90 dias não começa a correr. Serve para conferir as fotos de referência **antes** de cadastrar. Uma foto escura, tremida ou de perfil é cadastrada sem reclamação e só falha na comparação facial meses depois, em produção, um funcionário por vez. Aqui ela volta como aviso enquanto o lote ainda está na tela de alguém. Custa a mesma chamada de Rekognition por linha que cadastrar custaria — a economia não é financeira, é não guardar biometria que você já concluiu ser inservível.
  - `enrollments` object[], required
    - `userExternalId` string, required: Identificador do usuário no seu sistema.
    - `dryRun` boolean: Inspeciona sem gravar. Devolve o mesmo veredito que o endpoint de lote — `usable` / `marginal` / `rejected` com as métricas — e **não persiste nada**: nenhuma imagem no S3, nenhum registro, e o prazo de 90 dias não começa a correr. Mesma função dos dois lados, de propósito: uma foto não pode ser julgada de um jeito no lote e de outro aqui.
    - `image` string, byte, required: Imagem facial de referência codificada em base64 (JPEG).
    - `cpf` string, required: CPF do titular (11 dígitos, sem pontuação).
    - `source` 'ORGANIZATION_PROVIDED' | 'FIRST_LIVENESS' | 'DOCUMENT_PHOTO' | 'BANK_PROVIDED': Origem da imagem de enrollment — quem responde por aquele rosto e se o titular estava presente na captura. É o que separa, numa auditoria anos depois, a foto que a organização entregou da captura ao vivo e da que veio de um documento oficial. - `ORGANIZATION_PROVIDED` (padrão): foto vinda dos registros da própria organização — crachá, ficha de RH, folha. O titular não estava presente; quem responde pela imagem é a organização. - `FIRST_LIVENESS`: imagem capturada na primeira sessão de liveness do titular. Captura ao vivo, com o titular presente. - `DOCUMENT_PHOTO`: foto de documento (CNH/RG/passaporte). O rosto é extraído automaticamente. Requer `documentExtractionEnabled`. `BANK_PROVIDED` continua **aceito** como sinônimo de `ORGANIZATION_PROVIDED` e é normalizado na gravação — o valor devolvido e o que vai para a evidência são sempre o canônico. O nome antigo é de quando o único cliente era um banco; quem cadastra operadores de fábrica não deveria precisar enviá-lo.

## Response `200`

Lote processado. Pode conter linhas reprovadas — confira `failed` e
o `status` de cada item em `results`.

- object
  - `submitted` integer
  - `succeeded` integer
  - `failed` integer
  - `dryRun` boolean: Presente e `true` quando a requisição foi uma inspeção.
  - `usable` integer: `dryRun`: linhas boas, sem ressalva.
  - `marginal` integer: `dryRun`: linhas que **cadastrariam normalmente** mas têm ressalva. É a categoria que interessa — são justamente as que viram reprovação de comparação lá na frente.
  - `rejected` integer: `dryRun`: linhas que nem seriam cadastradas.
  - `results` object[]
    - `index` integer: Posição da linha no array enviado.
    - `referenceQuality` 'usable' | 'marginal' | 'rejected': **A foto serve como referência?** Separado do `status`, que diz o que aconteceu com a gravação. Uma linha pode ser `status: enrolled` com `referenceQuality: marginal` — é a combinação que interessa. Mesmo campo no `dryRun` e na gravação.
    - `quality` object: Medidas do Rekognition para o rosto detectado (0-100). Vêm no `dryRun` **e** na gravação real — a foto é guardada de qualquer jeito, e `faceConfidence` sozinho não diz se ela é boa referência.
      - `brightness` number, double
      - `sharpness` number, double
    - `pose` object: `dryRun`: rotação da cabeça em graus.
      - `yaw` number, double
      - `pitch` number, double
      - `roll` number, double
    - `faceCoverage` number, double: `dryRun`: área do rosto como fração do quadro (0-1). Rosto pequeno num retrato largo é detectável e ainda assim é referência fraca.
    - `warnings` string[]: Ressalvas legíveis por máquina, no `dryRun` e na gravação real. Vêm mesmo quando não há nenhuma — o array vazio é a resposta.
    - `userExternalId` string
    - `status` 'enrolled' | 'failed' | 'usable' | 'marginal' | 'rejected': `enrolled`/`failed` numa gravação real; `usable`/`marginal`/`rejected` num `dryRun`.
    - `enrollmentVersion` integer
    - `expiresAt` string, date-time: Quando a imagem de referência é apagada.
    - `faceConfidence` number, double
    - `error` string: Motivo, em pt-BR, quando `status` é `failed`.

## Other responses

- `400`: Lote vazio, acima de 25 itens, ou `userExternalId` repetido.
- `401`: Autenticação ausente ou inválida.

---

[API](https://skmtc.dev/signdocs/apis/signdocs-brasil-external-api.md) · [All operations](https://skmtc.dev/signdocs/apis/signdocs-brasil-external-api/llms.txt) · [OpenAPI document](https://skmtc.dev/signdocs/apis/signdocs-brasil-external-api/revisions/2d3805aed161?raw)
