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

# Cadastra uma conta de destino do pagamento por biometria, sem criar pagamento

> Põe uma conta de destino na lista da sua organização sem criar pagamento: é a porta de quem usa só a sessão e o widget, cujo flow escolhe a conta padrão nessa lista no painel. A regra é a MESMA do destination da criação do pagamento: em produção, a conta do CNPJ da sua organização recebe na hora; a de outro titular recebe 24 horas depois (available_from), com aviso por e-mail a quem administra a conta, que pode liberar antes ou bloquear no painel. Se a organização aceita só contas da lista, a conta de outro titular entra com release_required true e available_from null: ela só recebe depois que um administrador libera no painel, com o segundo fator, e nenhum relógio a libera. Uma mesma chave que cadastra muitas contas novas de terceiro de repente, acima da própria base, tem esse poder pausado por um tempo (422 destination_not_registered); as contas que já estão na lista seguem recebendo. A webhook_url é obrigatória: é o endereço dos eventos da conta. A que ainda não existe na sua organização vira um endereço de webhook deste ambiente; o segredo de assinatura dele volta em webhook_secret só no 201 que o criou. Idempotente pela identidade da conta (documento, instituição, agência, conta e tipo), sem janela e sem Idempotency-Key: a mesma conta ativa devolve 200 com Idempotent-Replay: true e a conta como está agora; conta revogada cadastrada de novo é outra conta, com outro id. Exige uma chave secreta criada COM o escopo pix_payments:write (chaves sem restrição não o têm) e o cadastro da organização aprovado. Não cobra e nada sai para fora na chamada. No sandbox (chave unifokal_test_) qualquer conta válida recebe na hora e nenhum dado seu sai.



## OpenAPI

````yaml /api-reference/openapi.json post /pix-destinations
openapi: 3.1.0
info:
  title: UNIFOKAL API
  version: v1
  summary: >-
    Verificação de identidade: sessão criada no servidor, jornada no widget,
    resultado no webhook.
  description: >-
    A versão vive no caminho (/v1); não existe header de versão. Adição
    compatível (campo, módulo ou chave nova) NÃO sobe a versão: ignore o que não
    conhecer. Todo erro tem a forma { error, message }: o código é estável, a
    mensagem não. Ids são prefixo + ULID. Webhooks são assinados (HMAC SHA-256
    no header X-IDSAAS-Signature, janela de 300s; o segredo é SEU, mínimo 32
    caracteres) e o header x-idsaas-event carrega o tipo do evento.
  termsOfService: https://unifokal.com/termos
  contact:
    name: UNIFOKAL
    url: https://docs.unifokal.com/
servers:
  - url: https://api.unifokal.com/v1
security: []
externalDocs:
  description: >-
    Documentação completa em https://docs.unifokal.com/. Briefing para agentes
    de IA em https://unifokal.com/llms.txt.
  url: https://docs.unifokal.com/
paths:
  /pix-destinations:
    post:
      summary: >-
        Cadastra uma conta de destino do pagamento por biometria, sem criar
        pagamento
      description: >-
        Põe uma conta de destino na lista da sua organização sem criar
        pagamento: é a porta de quem usa só a sessão e o widget, cujo flow
        escolhe a conta padrão nessa lista no painel. A regra é a MESMA do
        destination da criação do pagamento: em produção, a conta do CNPJ da sua
        organização recebe na hora; a de outro titular recebe 24 horas depois
        (available_from), com aviso por e-mail a quem administra a conta, que
        pode liberar antes ou bloquear no painel. Se a organização aceita só
        contas da lista, a conta de outro titular entra com release_required
        true e available_from null: ela só recebe depois que um administrador
        libera no painel, com o segundo fator, e nenhum relógio a libera. Uma
        mesma chave que cadastra muitas contas novas de terceiro de repente,
        acima da própria base, tem esse poder pausado por um tempo (422
        destination_not_registered); as contas que já estão na lista seguem
        recebendo. A webhook_url é obrigatória: é o endereço dos eventos da
        conta. A que ainda não existe na sua organização vira um endereço de
        webhook deste ambiente; o segredo de assinatura dele volta em
        webhook_secret só no 201 que o criou. Idempotente pela identidade da
        conta (documento, instituição, agência, conta e tipo), sem janela e sem
        Idempotency-Key: a mesma conta ativa devolve 200 com Idempotent-Replay:
        true e a conta como está agora; conta revogada cadastrada de novo é
        outra conta, com outro id. Exige uma chave secreta criada COM o escopo
        pix_payments:write (chaves sem restrição não o têm) e o cadastro da
        organização aprovado. Não cobra e nada sai para fora na chamada. No
        sandbox (chave unifokal_test_) qualquer conta válida recebe na hora e
        nenhum dado seu sai.
      operationId: createPixDestination
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreatePixDestinationRequest'
      responses:
        '200':
          description: 'A mesma conta já está ativa na lista: a conta como está agora.'
          headers:
            Idempotent-Replay:
              schema:
                type: string
                const: 'true'
              description: Sempre true na repetição.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PixDestinationCreated'
        '201':
          description: >-
            Conta cadastrada. Ela recebe a partir de available_from, ou depois
            da liberação quando release_required é true.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PixDestinationCreated'
        '400':
          description: >-
            Códigos estáveis: invalid_json, validation_error, webhook_required.
            Ramifique pelo campo error, nunca pela mensagem.
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/ErrorEnvelope'
                  - properties:
                      error:
                        enum:
                          - invalid_json
                          - validation_error
                          - webhook_required
        '401':
          description: >-
            Códigos estáveis: invalid_api_key. Ramifique pelo campo error, nunca
            pela mensagem.
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/ErrorEnvelope'
                  - properties:
                      error:
                        enum:
                          - invalid_api_key
        '403':
          description: >-
            Códigos estáveis: credential_type_not_allowed,
            organization_suspended, test_key_used_in_production,
            insufficient_scope, ip_not_allowed, onboarding_required. Ramifique
            pelo campo error, nunca pela mensagem.
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/ErrorEnvelope'
                  - properties:
                      error:
                        enum:
                          - credential_type_not_allowed
                          - organization_suspended
                          - test_key_used_in_production
                          - insufficient_scope
                          - ip_not_allowed
                          - onboarding_required
        '413':
          description: >-
            Códigos estáveis: payload_too_large. Ramifique pelo campo error,
            nunca pela mensagem.
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/ErrorEnvelope'
                  - properties:
                      error:
                        enum:
                          - payload_too_large
        '422':
          description: >-
            Códigos estáveis: webhook_url_invalid, institution_unknown,
            destination_not_registered. Ramifique pelo campo error, nunca pela
            mensagem.
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/ErrorEnvelope'
                  - properties:
                      error:
                        enum:
                          - webhook_url_invalid
                          - institution_unknown
                          - destination_not_registered
        '429':
          description: >-
            Códigos estáveis: rate_limited. Ramifique pelo campo error, nunca
            pela mensagem.
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/ErrorEnvelope'
                  - properties:
                      error:
                        enum:
                          - rate_limited
      security:
        - secretKey: []
components:
  schemas:
    CreatePixDestinationRequest:
      type: object
      properties:
        destination:
          type: object
          properties:
            holder_name:
              type: string
              minLength: 1
              maxLength: 140
              pattern: ^[^\u0000-\u001f\u007f-\u009f]*$
              description: Espaços nas pontas são removidos antes da validação.
            holder_document:
              type: string
              pattern: ^\d{11}$|^[0-9A-Z]{12}\d{2}$
            ispb:
              type: string
              pattern: ^\d{8}$
            branch:
              type: string
              pattern: ^\d{1,4}$
            account:
              type: string
              pattern: ^\d{1,20}$
            account_type:
              type: string
              enum:
                - checking
                - savings
          required:
            - holder_name
            - holder_document
            - ispb
            - branch
            - account
            - account_type
          description: >-
            A conta por extenso, no MESMO formato do destination da criação do
            pagamento: titular, CPF ou CNPJ (dígito verificador conferido), ISPB
            da instituição, agência, conta e tipo. A identidade da conta é o
            documento, a instituição, a agência, a conta e o tipo; o nome do
            titular não entra nela.
        webhook_url:
          type: string
          minLength: 1
          maxLength: 2048
          description: >-
            Obrigatório (sem ele, 400 webhook_required): o endereço https do seu
            servidor que recebe os eventos desta conta. Um endereço igual a um
            que você já tem neste ambiente é reaproveitado; um novo nasce aqui e
            o segredo de assinatura volta em webhook_secret só no 201. Endereço
            interno ou sem https é 422 webhook_url_invalid. A conta guarda o
            endereço do primeiro cadastro.
      required:
        - destination
        - webhook_url
    PixDestinationCreated:
      type: object
      description: >-
        A resposta do cadastro: o objeto pix_destination e o webhook_secret.
        Campo novo pode surgir sem subir a versão: ignore chave desconhecida.
      required:
        - id
        - object
        - livemode
        - status
        - in_review
        - available_from
        - release_required
        - ownership
        - holder_name
        - holder_document
        - ispb
        - branch
        - account
        - account_type
        - created_at
        - revoked_at
        - webhook_secret
      properties:
        id:
          $ref: '#/components/schemas/PixDestinationId'
        object:
          type: string
          const: pix_destination
        livemode:
          type: boolean
          description: true em produção (chave unifokal_live_), false no sandbox.
        status:
          type: string
          enum:
            - active
            - revoked
          description: >-
            active: na lista; revoked: revogada ou bloqueada no painel (não
            recebe mais).
        in_review:
          type: boolean
          description: >-
            true enquanto a conta ativa ainda não recebe: a espera de 24 horas
            da conta nova de outro titular, ou a liberação de um administrador
            (release_required).
        available_from:
          type:
            - string
            - 'null'
          format: date-time
          description: >-
            Desde quando a conta recebe. null quando ela espera a liberação de
            uma pessoa (release_required true), porque nenhum relógio a libera.
        release_required:
          type: boolean
          description: >-
            true quando a conta de outro titular espera a liberação de um
            administrador da organização no painel, com o segundo fator.
        ownership:
          type: string
          enum:
            - organization
            - third_party
          description: 'organization: o CNPJ da sua organização; third_party: outro titular.'
        holder_name:
          type: string
        holder_document:
          type: string
          description: CPF ou CNPJ do titular, mascarado.
        ispb:
          type: string
          pattern: ^\d{8}$
        branch:
          type: string
        account:
          type: string
          description: Número da conta, mascarado.
        account_type:
          type: string
          enum:
            - checking
            - savings
        created_at:
          type: string
          format: date-time
        revoked_at:
          type:
            - string
            - 'null'
          format: date-time
        webhook_secret:
          type:
            - string
            - 'null'
          description: >-
            O segredo de assinatura (X-IDSAAS-Signature) do endereço de webhook
            criado por esta chamada a partir da webhook_url. Só aparece no 201
            que criou o endereço; null na repetição e quando o endereço já
            existia. Não registre em log.
    ErrorEnvelope:
      type: object
      description: >-
        Todo erro da API tem exatamente esta forma. O campo error é um código
        estável (contrato); message é texto livre e pode mudar sem aviso.
      required:
        - error
        - message
      properties:
        error:
          type: string
          description: Código estável do erro. Ramifique por ele.
        message:
          type: string
          description: Texto explicativo. NÃO é contrato.
      additionalProperties: false
    PixDestinationId:
      type: string
      pattern: ^pxr_[0-9A-HJKMNP-TV-Z]{26}$
      description: >-
        Id da conta de destino da sua lista (pxr_ + ULID), cadastrada pelo POST
        /v1/pix-destinations ou na criação de um pagamento.
  securitySchemes:
    secretKey:
      type: http
      scheme: bearer
      description: >-
        Chave secreta (unifokal_live_ em produção, unifokal_test_ no sandbox: 64
        hex mais CRC-32) no Authorization: Bearer. Só no seu servidor: nunca no
        browser ou app (o widget monta apenas com o id vs_ da sessão). Não
        existe chave publishable.

````

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