> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pilotstatus.com.br/llms.txt
> Use this file to discover all available pages before exploring further.

# Enviar novo documento

> ⚠️ **Esta chamada é real**: ela envia um novo documento de identidade para a verificação do workspace, substituindo o anterior, e pode **decidir** a verificação.

Substitui o documento da verificação atual e responde **200** com o estado. O corpo é **JSON** (`Content-Type: application/json`), não multipart: `{ "document": "data:…;base64,…" }`, com as mesmas regras de arquivo de `POST /v1/phone-lines/verification`, e conta no mesmo limite de envios (10 por hora por workspace → 429 `RATE_LIMITED`). É aceito em dois estados:

- **`PENDING_CONTACT`** — para substituir o documento que você enviou. Faça isso quando `document.status` for `UNREADABLE` ou `UNCLEAR`: não conseguimos ler do arquivo um número confiável, então envie uma foto mais nítida ou o PDF. Se você confirmar o último código sem substituí-lo, a verificação vai para análise manual (`IN_REVIEW`, `reviewReason: "DOCUMENT_CHECK"`).
- **`NEEDS_DOCUMENT`** — o revisor pediu outro documento (`reviewNote` pode dizer qual). Os códigos de contato já foram confirmados, então o novo documento leva a verificação direto a uma nova decisão, nesta mesma resposta.

Em qualquer outro estado, responde 409 `VERIFICATION_WRONG_STATE`; sem nenhuma verificação, 404 `VERIFICATION_NOT_FOUND`. Sem `Idempotency-Key`: um documento substitui o anterior. Exige uma chave **com escopo de tenant**, como todo endpoint `/v1/phone-lines` (uma chave com escopo de número recebe `403 NUMBER_SCOPE_NOT_ALLOWED`). Permissão `phone_lines:purchase`, a mesma da compra: com um token OAuth/MCP, só o **OWNER** do workspace pode chamar (`403 PERMISSION_DENIED` caso contrário). É a mesma verificação do painel (**Linhas** → **Comprar linhas**): o que você fizer por um caminho aparece no outro. A resposta é o objeto de estado da verificação, enviado com `Cache-Control: no-store`; o número do documento e os contatos voltam mascarados.

> [!WARNING]
>
> **Isto substitui o documento da sua verificação de identidade real.**


## OpenAPI

````yaml openapi.pt.json POST /v1/phone-lines/verification/document
openapi: 3.1.0
info:
  title: API Pilot Status
  version: 1.0.0
  license:
    name: Pilot Status Terms of Service
    url: https://pilotstatus.com.br/terms
  description: >-
    API REST pública do Pilot Status. Autentique com o header `x-api-key:
    ps_...` (ou `x-api-key-id`). Base URL: https://pilotstatus.com.br
servers:
  - url: https://pilotstatus.com.br
security:
  - apiKey: []
  - apiKeyId: []
paths:
  /v1/phone-lines/verification/document:
    post:
      tags:
        - Phone Lines
      summary: Enviar um novo documento
      description: >-
        ⚠️ **Esta chamada é real**: ela envia um novo documento de identidade
        para a verificação do workspace, substituindo o anterior, e pode
        **decidir** a verificação.


        Substitui o documento da verificação atual e responde **200** com o
        estado. O corpo é **JSON** (`Content-Type: application/json`), não
        multipart: `{ "document": "data:…;base64,…" }`, com as mesmas regras de
        arquivo de `POST /v1/phone-lines/verification`, e conta no mesmo limite
        de envios (10 por hora por workspace → 429 `RATE_LIMITED`). É aceito em
        dois estados:


        - **`PENDING_CONTACT`** — para substituir o documento que você enviou.
        Faça isso quando `document.status` for `UNREADABLE` ou `UNCLEAR`: não
        conseguimos ler do arquivo um número confiável, então envie uma foto
        mais nítida ou o PDF. Se você confirmar o último código sem
        substituí-lo, a verificação vai para análise manual (`IN_REVIEW`,
        `reviewReason: "DOCUMENT_CHECK"`).

        - **`NEEDS_DOCUMENT`** — o revisor pediu outro documento (`reviewNote`
        pode dizer qual). Os códigos de contato já foram confirmados, então o
        novo documento leva a verificação direto a uma nova decisão, nesta mesma
        resposta.


        Em qualquer outro estado, responde 409 `VERIFICATION_WRONG_STATE`; sem
        nenhuma verificação, 404 `VERIFICATION_NOT_FOUND`. Sem
        `Idempotency-Key`: um documento substitui o anterior. Exige uma chave
        **com escopo de tenant**, como todo endpoint `/v1/phone-lines` (uma
        chave com escopo de número recebe `403 NUMBER_SCOPE_NOT_ALLOWED`).
        Permissão `phone_lines:purchase`, a mesma da compra: com um token
        OAuth/MCP, só o **OWNER** do workspace pode chamar (`403
        PERMISSION_DENIED` caso contrário). É a mesma verificação do painel
        (**Linhas** → **Comprar linhas**): o que você fizer por um caminho
        aparece no outro. A resposta é o objeto de estado da verificação,
        enviado com `Cache-Control: no-store`; o número do documento e os
        contatos voltam mascarados.
      operationId: post_phone_lines_verification_document
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - document
              additionalProperties: false
              properties:
                document:
                  type: string
                  description: >-
                    O arquivo do documento como **data URI em base64**:
                    `data:<tipo>;base64,<conteúdo>`, codificado sem quebras de
                    linha. Tipos: `application/pdf`, `image/jpeg`, `image/png`,
                    `image/webp`; no máximo **10 MB** de arquivo (cerca de 14 MB
                    depois de codificado). Para CNPJ: cartão CNPJ, contrato
                    social ou comprovante de inscrição. Para CPF: RG, CNH ou
                    comprovante de inscrição no CPF, com o número legível.
                  example: data:application/pdf;base64,JVBERi0xLjQKJcOkw7zDtsOfCg==
            example:
              document: data:application/pdf;base64,JVBERi0xLjQKJcOkw7zDtsOfCg==
      responses:
        '200':
          description: Documento substituído; o estado da verificação
          headers:
            Cache-Control:
              description: Sempre `no-store`.
              schema:
                type: string
                enum:
                  - no-store
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    enum:
                      - NONE
                      - PENDING_CONTACT
                      - IN_REVIEW
                      - APPROVED
                      - NEEDS_DOCUMENT
                      - REJECTED
                    description: >-
                      `NONE` (nunca iniciada), `PENDING_CONTACT` (esperando os
                      códigos de contato e, se `document.status` indicar, um
                      documento melhor), `IN_REVIEW` (concluída, esperando uma
                      pessoa conferir — compra permitida), `APPROVED`
                      (verificada — compra permitida), `NEEDS_DOCUMENT` (o
                      revisor pediu outro documento) ou `REJECTED` (definitivo —
                      fale com o suporte). O webhook
                      `phone_line.verification_updated` usa os mesmos valores
                      para os quatro últimos.
                  canPurchase:
                    type: boolean
                    description: >-
                      Se `POST /v1/phone-lines` é permitido agora: `true` para
                      `APPROVED` e `IN_REVIEW`.
                  verification:
                    type: object
                    nullable: true
                    description: '`null` para `NONE`.'
                    properties:
                      id:
                        type: string
                        description: >-
                          Identifica a verificação — é o `verificationId` do
                          evento de webhook, e o que o suporte vai pedir.
                      documentType:
                        type: string
                        enum:
                          - CNPJ
                          - CPF
                      documentNumber:
                        type: string
                        description: >-
                          **Mascarado**: `**.***.333/0001-**` (CNPJ) ou
                          `***.456.789-**` (CPF). O número completo nunca é
                          retornado.
                      legalName:
                        type: string
                        nullable: true
                        description: >-
                          A razão social na Receita (CNPJ). `null` para CPF, e
                          quando a Receita não pôde ser consultada.
                      contact:
                        type: object
                        properties:
                          email:
                            type: string
                            description: >-
                              O e-mail de contato, mascarado
                              (`a***@example.com`).
                          whatsapp:
                            type: string
                            nullable: true
                            description: >-
                              O WhatsApp de contato, mascarado
                              (`+5511****0000`).
                          requiredChannels:
                            type: array
                            items:
                              type: string
                              enum:
                                - WHATSAPP
                                - EMAIL
                            description: >-
                              `WHATSAPP` e/ou `EMAIL`: os códigos de que esta
                              verificação precisa. Fica congelada quando a
                              verificação começa. Pela API, `EMAIL` é sempre
                              exigido.
                          confirmedChannels:
                            type: array
                            items:
                              type: string
                              enum:
                                - WHATSAPP
                                - EMAIL
                            description: Os canais exigidos já confirmados.
                          pendingChannels:
                            type: array
                            items:
                              type: string
                              enum:
                                - WHATSAPP
                                - EMAIL
                            description: Os canais exigidos que ainda esperam o código.
                      document:
                        type: object
                        properties:
                          status:
                            type: string
                            enum:
                              - RECEIVED
                              - UNREADABLE
                              - UNCLEAR
                              - REQUESTED
                              - MISSING
                            description: >-
                              `RECEIVED` (o documento foi recebido),
                              `UNREADABLE` (não encontramos nenhum número no
                              arquivo), `UNCLEAR` (encontramos números, mas
                              nenhum em que pudéssemos confiar), `REQUESTED` (o
                              revisor pediu outro documento) ou `MISSING` (ainda
                              sem documento). Nos quatro últimos, envie um novo
                              documento com `POST
                              /v1/phone-lines/verification/document`.
                      reviewReason:
                        type: string
                        nullable: true
                        enum:
                          - REGISTRY_UNAVAILABLE
                          - DOCUMENT_CHECK
                          - null
                        description: >-
                          Só em `IN_REVIEW`: `REGISTRY_UNAVAILABLE` (não foi
                          possível consultar a Receita) ou `DOCUMENT_CHECK` (o
                          documento precisa ser conferido). `null` nos outros
                          casos.
                      reviewNote:
                        type: string
                        nullable: true
                        description: >-
                          A mensagem do revisor, só em `REJECTED` e
                          `NEEDS_DOCUMENT`. `null` nos outros casos — e pode ser
                          `null` nesses também.
                      createdAt:
                        type: string
                        format: date-time
                        description: ISO 8601 — quando esta verificação foi enviada.
                      updatedAt:
                        type: string
                        format: date-time
                        description: ISO 8601 — a última mudança dela.
              examples:
                pendingContact:
                  summary: Ainda esperando um código
                  value:
                    status: PENDING_CONTACT
                    canPurchase: false
                    verification:
                      id: cmg5k0v3r0000vf8example7k
                      documentType: CNPJ
                      documentNumber: '**.***.333/0001-**'
                      legalName: ACME LTDA
                      contact:
                        email: a***@example.com
                        whatsapp: +5511****0000
                        requiredChannels:
                          - WHATSAPP
                          - EMAIL
                        confirmedChannels:
                          - WHATSAPP
                        pendingChannels:
                          - EMAIL
                      document:
                        status: RECEIVED
                      reviewReason: null
                      reviewNote: null
                      createdAt: '2026-10-01T13:55:02.000Z'
                      updatedAt: '2026-10-01T13:56:40.000Z'
                approved:
                  summary: De volta de NEEDS_DOCUMENT — aprovada
                  value:
                    status: APPROVED
                    canPurchase: true
                    verification:
                      id: cmg5k0v3r0000vf8example7k
                      documentType: CNPJ
                      documentNumber: '**.***.333/0001-**'
                      legalName: ACME LTDA
                      contact:
                        email: a***@example.com
                        whatsapp: +5511****0000
                        requiredChannels:
                          - WHATSAPP
                          - EMAIL
                        confirmedChannels:
                          - WHATSAPP
                          - EMAIL
                        pendingChannels: []
                      document:
                        status: RECEIVED
                      reviewReason: null
                      reviewNote: null
                      createdAt: '2026-10-01T13:55:02.000Z'
                      updatedAt: '2026-10-01T13:57:31.000Z'
        '400':
          description: >-
            `INVALID_BODY` (não é um objeto JSON), `UNKNOWN_FIELDS` (qualquer
            campo além de `document`), `INVALID_DOCUMENT` (não é data URI em
            base64) ou `DOCUMENT_TYPE_UNSUPPORTED` (não é PDF/JPEG/PNG/WEBP).
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Frase em inglês e frase em português separadas por ` | `.
                  code:
                    type: string
                    description: Código de erro estável — decida por ele, nunca pelo texto.
                  details:
                    type: object
                    description: >-
                      Só em erros de validação: `unknownFields` (array) ou
                      `maxLength` (número).
                    additionalProperties: true
              examples:
                invalidDocument:
                  summary: document não é data URI
                  value:
                    error: >-
                      document must be the file as a base64 data URI, e.g.
                      data:application/pdf;base64,JVBERi0x… | document deve ser
                      o arquivo como data URI em base64, ex.:
                      data:application/pdf;base64,JVBERi0x…
                    code: INVALID_DOCUMENT
                documentTypeUnsupported:
                  summary: Tipo de arquivo não aceito
                  value:
                    error: >-
                      Send a PDF, JPG, PNG or WEBP file. | Envie um arquivo PDF,
                      JPG, PNG ou WEBP.
                    code: DOCUMENT_TYPE_UNSUPPORTED
                unknownFields:
                  summary: Campo além de document
                  value:
                    error: >-
                      Unknown field(s): documentType. This endpoint accepts only
                      "document". | Campo(s) desconhecido(s): documentType. Este
                      endpoint aceita apenas "document".
                    code: UNKNOWN_FIELDS
                    details:
                      unknownFields:
                        - documentType
        '401':
          description: >-
            Header `x-api-key` / `x-api-key-id` (ou token OAuth Bearer) ausente
            ou inválido. Este corpo não traz `code`.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
              example:
                error: Invalid API key
        '403':
          description: >-
            Chave com escopo de número ou grant OAuth por número
            (`NUMBER_SCOPE_NOT_ALLOWED` — use a chave com escopo de tenant);
            token OAuth/MCP de um usuário que não é o OWNER do workspace
            (`PERMISSION_DENIED`) ou que não é mais membro ativo
            (`WORKSPACE_MEMBERSHIP_REQUIRED`); workspace arquivado
            (`WORKSPACE_ARCHIVED`). Os erros de escopo e de papel trazem um
            `error` só em inglês.. `TENANT_REQUIRED`: credencial sem workspace
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
              examples:
                numberScope:
                  summary: Chave com escopo de número
                  value:
                    error: This endpoint requires a tenant-scoped API key
                    code: NUMBER_SCOPE_NOT_ALLOWED
                permission:
                  summary: Usuário OAuth/MCP não é o OWNER
                  value:
                    error: >-
                      Your workspace role does not allow this action
                      (phone_lines:purchase).
                    code: PERMISSION_DENIED
                membership:
                  summary: Usuário OAuth/MCP não é mais membro ativo
                  value:
                    error: >-
                      The user behind this token is not an active member of this
                      workspace.
                    code: WORKSPACE_MEMBERSHIP_REQUIRED
                archived:
                  summary: Workspace arquivado
                  value:
                    error: >-
                      This workspace has been archived and its API is closed. |
                      Este workspace foi arquivado e sua API está encerrada.
                    code: WORKSPACE_ARCHIVED
                tenantRequired:
                  summary: Credencial sem workspace
                  value:
                    error: This credential is not bound to a workspace.
                    code: TENANT_REQUIRED
        '404':
          description: '`VERIFICATION_NOT_FOUND`: nada foi enviado neste workspace.'
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
              example:
                error: Verification not found. | Verificação não encontrada.
                code: VERIFICATION_NOT_FOUND
        '409':
          description: >-
            `VERIFICATION_WRONG_STATE`: a verificação não está em
            `PENDING_CONTACT` nem em `NEEDS_DOCUMENT`.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
              example:
                error: >-
                  The verification is not in a state that allows this. | A
                  verificação não está em um estado que permita isso.
                code: VERIFICATION_WRONG_STATE
        '413':
          description: O arquivo tem mais de 10 MB.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
              example:
                error: The file is larger than 10 MB. | O arquivo tem mais de 10 MB.
                code: DOCUMENT_TOO_LARGE
        '429':
          description: >-
            `RATE_LIMITED`: mais de 10 envios na hora para este workspace
            (somando este endpoint e `POST /v1/phone-lines/verification`).
            Aguarde `Retry-After` segundos.
          headers:
            Retry-After:
              description: Segundos a esperar antes do próximo envio.
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
                  retryAfterSeconds:
                    type: integer
                    description: Segundos até um novo envio ser aceito.
              example:
                error: >-
                  Too many verification submissions: at most 10 per hour per
                  workspace. Try again later. | Envios de verificação demais: no
                  máximo 10 por hora por workspace. Tente de novo mais tarde.
                code: RATE_LIMITED
                retryAfterSeconds: 1820
        '500':
          description: Falha inesperada. Tente de novo.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
              example:
                error: Unexpected error. | Erro inesperado.
                code: INTERNAL_ERROR
components:
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: x-api-key
      description: Sua chave de API ps_
    apiKeyId:
      type: apiKey
      in: header
      name: x-api-key-id
      description: Id da chave de API (alternativa ao x-api-key)

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.