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

# Register PIX key

> Registers a new PIX key after validating the request, enforcing the per-account key limit, and successfully synchronizing with BACEN DICT. Registration fails closed if BACEN DICT is unavailable or rejects the key. A refusal BACEN would give for the same rule is answered locally with BACEN's own token and status 400: EntryLimitExceeded (the account holds its key limit), EntryAlreadyExists (the key is held for the same participant and owner), EntryKeyOwnedByDifferentPerson (held for another owner) or EntryKeyInCustodyOfDifferentParticipant (held for the same owner at another participant of this deployment).



## OpenAPI

````yaml /pt/openapi/v3-current/spi-dict.yaml post /api/v1/dict/keys
openapi: 3.1.0
info:
  contact:
    email: contact@lerian.studio
    name: Lerian Studio
    url: https://lerian.studio
  description: >-
    OpenAPI 3.1 surface for the DICT (Diretório de Identificadores de Contas
    Transacionais) capability of Lerian SPI, the direct integration between the
    institution and the Brazilian Instant Payment System (SPI/Pix). It covers
    the PIX key lifecycle, portability and ownership claims, the MED 2.0 dispute
    surface (infraction reports, refunds, fraud markers, and funds recoveries),
    antifraud statistics, synchronous DICT reports, and the internal operations
    that keep the key directory consistent.
  license:
    name: Lerian Studio General License
  title: Lerian SPI — DICT API
  version: 1.0.0
servers:
  - url: https://api.example.com
    description: >-
      Replace the example host with the URL provided during environment
      onboarding.
security: []
tags:
  - description: 'PIX key lifecycle: register, list, search, lookup, delete, and statistics.'
    name: Keys
  - description: >-
      PIX key portability and ownership claims through their full lifecycle
      (initiate, confirm, reject, cancel, acknowledge, complete).
    name: Claims
  - description: 'DICT infraction reports: list and retrieve.'
    name: Infractions
  - description: 'DICT refund requests: create, list, and retrieve.'
    name: Refunds
  - description: 'PIX fraud markers: create, list, and statistics.'
    name: Fraud Markers
  - description: >-
      Durable MED operation-intent status: the operationId every
      create/lifecycle-transition backlog route returns or references on every
      outcome, queryable independently of the business resource.
    name: Operations
  - description: >-
      Synchronous reports over Lerian SPI's own DICT record: COUNT(*) summaries
      of keys (by type/status) and claims (by type/status + open-past-deadline).
      COUNT-only — DICT holds no money.
    name: Reports
  - description: >-
      DICT 8.4 section 13.2.3 query monitoring: read the query indicators, block
      or release an end user after a founded suspicion, and read the DICT
      request-limiting token buckets.
    name: Query Monitoring
  - description: >-
      DICT synchronism checks transported to BACEN for the participant named in
      X-ISPB: sync verification, CID resolution and CID set events, projected
      verbatim.
    name: VSync
paths:
  /api/v1/dict/keys:
    post:
      tags:
        - Keys
      summary: Register PIX key
      description: >-
        Registers a new PIX key after validating the request, enforcing the
        per-account key limit, and successfully synchronizing with BACEN DICT.
        Registration fails closed if BACEN DICT is unavailable or rejects the
        key. A refusal BACEN would give for the same rule is answered locally
        with BACEN's own token and status 400: EntryLimitExceeded (the account
        holds its key limit), EntryAlreadyExists (the key is held for the same
        participant and owner), EntryKeyOwnedByDifferentPerson (held for another
        owner) or EntryKeyInCustodyOfDifferentParticipant (held for the same
        owner at another participant of this deployment).
      operationId: registerKey
      parameters:
        - description: Idempotency key, max 255 characters
          in: header
          name: X-Idempotency
          required: true
          schema:
            description: Idempotency key, max 255 characters
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RegisterKeyRequest'
              description: >-
                PIX key to register (key type, value, owner identity, and
                participant ISPB); registration fails closed if BACEN DICT
                rejects or is unavailable
        required: true
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PIXKeyResponse'
                description: Registered PIX key with its assigned status
          description: Created
        '400':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Detail'
          description: Bad Request
        '403':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Detail'
          description: Forbidden
        '409':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Detail'
          description: Conflict
        '422':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Detail'
          description: Unprocessable Entity
        '429':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Detail'
          description: Too Many Requests
        '500':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Detail'
          description: Internal Server Error
        '503':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Detail'
          description: Service Unavailable
        default:
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Detail'
          description: Error
      security:
        - BearerAuth: []
components:
  schemas:
    RegisterKeyRequest:
      additionalProperties: false
      properties:
        accountNumber:
          description: >-
            Account number, 1 to 20 digits. BACEN admits letters here; this rail
            does not, and the door states the narrower rule it actually applies.
          examples:
            - '9988776'
          pattern: ^[0-9]{1,20}$
          type: string
        accountType:
          description: >-
            BACEN account type: CACC (current), SVGS (savings), TRAN
            (transactional), SLRY (salary), or OTHR (other).
          enum:
            - CACC
            - SVGS
            - TRAN
            - SLRY
            - OTHR
          examples:
            - CACC
          type: string
        branch:
          description: Account branch (1..4 digits), optional.
          examples:
            - '0001'
          type: string
        keyType:
          description: 'PIX key type: CPF, CNPJ, EMAIL, PHONE, or EVP (random key).'
          enum:
            - CPF
            - CNPJ
            - EMAIL
            - PHONE
            - EVP
          examples:
            - CPF
          type: string
        keyValue:
          description: >-
            PIX key value, formatted according to keyType: 11 digits for CPF, 14
            alphanumeric characters for CNPJ, +55 plus an 11-digit mobile number
            for PHONE, an email address for EMAIL. REQUIRED for those four types
            and REFUSED for EVP — the chave aleatória is generated by the DICT,
            and the value it returns is the key.
          examples:
            - '12345678901'
          type: string
        openingDate:
          description: >-
            Account opening date, RFC 3339 (the FI account's opening date, not
            the key's creation moment).
          examples:
            - '2020-01-15T00:00:00Z'
          format: date-time
          type: string
        ownerName:
          description: >-
            Full legal name of the key owner (at most 150 characters). The
            accepted character set differs by owner type — letters, apostrophe,
            hyphen and space for an individual; printable Latin-1 for a company
            — and is applied by the service, since one schema pattern cannot
            depend on the tax id's length.
          examples:
            - João Silva
          maxLength: 150
          minLength: 1
          type: string
        ownerTaxId:
          description: >-
            Owner tax identifier: 11 digits for a CPF (individuals), 14
            alphanumeric characters for a CNPJ (businesses, IN RFB 2.229/2024).
            Shaped as the SPI wire type PICpfCnpj. The check digits are verified
            by the service.
          examples:
            - '12345678901'
          pattern: ^([0-9]{11}|[0-9A-Za-z]{12}[0-9]{2})$
          type: string
        ownerTradeName:
          description: Owner trade name (legal-entity / CNPJ owners), optional.
          examples:
            - Silva ME
          type: string
        ownerType:
          description: >-
            BACEN's Person discriminator for the key owner, sent verbatim on
            createEntry. Optional: omitted, it is resolved from ownerTaxId (11
            characters natural, 14 legal). Supplied, it binds — a value
            contradicting ownerTaxId is refused, never honoured.
          enum:
            - NATURAL_PERSON
            - LEGAL_PERSON
          examples:
            - NATURAL_PERSON
          type: string
        participantISPB:
          description: >-
            Owning participant ISPB, the BACEN institution identifier (8 digits
            or uppercase letters).
          examples:
            - '12345678'
          pattern: ^[0-9A-Z]{8}$
          type: string
        possessionEvidence:
          $ref: '#/components/schemas/PossessionEvidenceRequest'
          description: >-
            Attestation that key possession was verified, as DICT 8.4 section
            2.1 requires. Optional for CPF, CNPJ, EMAIL and PHONE keys; refused
            for EVP, where nothing is possessed. Omitting it does not refuse the
            registration — the absence is recorded in the key's audit trail.
            Supplied, it is validated in full and a malformed attestation is
            refused.
        reason:
          description: >-
            Why this key is being registered, sent verbatim to BACEN as
            createEntry's Reason. USER_REQUESTED when an end user asked for the
            key, RECONCILIATION when restoring a binding this PSP already holds
            after a divergence. Required: only the participant holds the fact
            that decides it, so there is no default.
          enum:
            - USER_REQUESTED
            - RECONCILIATION
          examples:
            - USER_REQUESTED
          type: string
        requestId:
          description: >-
            Idempotency key for this registration, a version 4 UUID, sent
            verbatim to BACEN as createEntry's RequestId. Required — never
            invented here. BACEN binds it to the vinculo for life and refuses a
            reuse under different binding parameters, so send a fresh value per
            registration. This rail does not refuse a reused value locally: the
            rule is BACEN's, enforced there and relayed. Must be version 4:
            every other version derives from a clock, a node id or a hashed
            name, so two different registrations can collide by construction.
            Distinct from the X-Idempotency header, which is this rail's own
            de-duplication and never reaches BACEN.
          examples:
            - b2696bf1-0a51-48b0-ab4a-8af2dff440af
          format: uuid
          type: string
      required:
        - keyType
        - ownerName
        - ownerTaxId
        - participantISPB
        - accountNumber
        - accountType
        - openingDate
        - requestId
        - reason
      type: object
    PIXKeyResponse:
      additionalProperties: false
      properties:
        accountNumber:
          description: Account number (1..20 digits), omitted for a tuple-less key.
          examples:
            - '9988776'
          type: string
        accountType:
          description: >-
            BACEN account type (CACC, SVGS, TRAN, SLRY, OTHR), omitted for a
            tuple-less key.
          enum:
            - CACC
            - SVGS
            - TRAN
            - SLRY
            - OTHR
          examples:
            - CACC
          type: string
        bacen:
          $ref: '#/components/schemas/BACENEnvelopeResponse'
          description: >-
            BACEN's own operational envelope for its most recent interaction on
            this key; omitted when no BACEN interaction has ever landed on it.
        branch:
          description: Account branch (1..4 digits), omitted when unset.
          examples:
            - '0001'
          type: string
        createdAt:
          description: >-
            Key creation timestamp, RFC 3339 (UTC) — OUR row's local timestamp,
            not BACEN's; see creationDate for the DICT's own binding-creation
            instant.
          examples:
            - '2025-03-07T14:30:00Z'
          type: string
        creationDate:
          description: >-
            BACEN's own creation instant for this key/account/owner binding, as
            the DICT answered it; omitted when BACEN's answer carried none.
          examples:
            - '2020-01-15T00:00:00Z'
          format: date-time
          type: string
        id:
          description: Unique PIX key identifier (UUID) assigned by the service.
          examples:
            - 550e8400-e29b-41d4-a716-446655440000
          type: string
        keyOwnershipDate:
          description: >-
            Instant from which the owner has held uninterrupted possession of
            this key per BACEN; may differ from creationDate after a
            portability. Omitted when BACEN's answer carried none.
          examples:
            - '2020-01-15T00:00:00Z'
          format: date-time
          type: string
        keyType:
          description: 'PIX key type: CPF, CNPJ, EMAIL, PHONE, or EVP (random key).'
          examples:
            - CPF
          type: string
        keyValue:
          description: PIX key value in its canonical format for the key type.
          examples:
            - '12345678901'
          type: string
        openingDate:
          description: Account opening date, RFC 3339, omitted for a tuple-less key.
          examples:
            - '2020-01-15T00:00:00Z'
          format: date-time
          type: string
        ownerName:
          description: Full legal name of the key owner.
          examples:
            - João Silva
          type: string
        ownerTaxId:
          description: >-
            Owner tax identifier: 11 digits for a CPF, 14 alphanumeric
            characters for a CNPJ (IN RFB 2.229/2024).
          examples:
            - '12345678901'
          type: string
        ownerTradeName:
          description: Owner trade name (legal-entity owners), omitted when unset.
          examples:
            - Silva ME
          type: string
        ownerType:
          description: >-
            BACEN's own Person discriminator for the owner, as the DICT
            published it — not the value the registration declared, which is
            refused when the two could disagree. Omitted when BACEN's answer
            carried none.
          enum:
            - NATURAL_PERSON
            - LEGAL_PERSON
          examples:
            - NATURAL_PERSON
          type: string
        participantISPB:
          description: >-
            Owning participant ISPB, the BACEN institution identifier (8 digits
            or uppercase letters).
          examples:
            - '12345678'
          type: string
        requestId:
          description: >-
            The participant's own identifier for the registration that created
            this binding, echoed back. It is the value BACEN holds against the
            vinculo for life, so it is what a DICT support case and a retry are
            addressed by. Omitted for a key registered before this field
            existed, which had no caller to state one.
          examples:
            - b2696bf1-0a51-48b0-ab4a-8af2dff440af
          format: uuid
          type: string
        status:
          description: 'Key lifecycle status: ACTIVE or PENDING_CLAIM.'
          examples:
            - ACTIVE
          type: string
        updatedAt:
          description: Timestamp of the last update to the key, RFC 3339 (UTC).
          examples:
            - '2025-03-07T14:30:00Z'
          type: string
      required:
        - id
        - keyType
        - keyValue
        - ownerName
        - ownerTaxId
        - participantISPB
        - status
        - createdAt
        - updatedAt
      type: object
    Detail:
      additionalProperties: false
      properties:
        code:
          description: >-
            Stable, machine-readable domain error code scoped to the emitting
            service (format: <SERVICE>-NNNN).
          type: string
        correlationId:
          description: Request-scoped correlation identifier echoing X-Request-ID.
          examples:
            - req-7a3f9c2e
          type: string
        detail:
          description: >-
            A human-readable explanation specific to this occurrence of the
            problem.
          examples:
            - Property foo is required but is missing.
          type: string
        errors:
          description: Optional list of individual error details
          items:
            $ref: '#/components/schemas/ErrorDetail'
          type:
            - array
            - 'null'
        instance:
          description: >-
            A URI reference that identifies the specific occurrence of the
            problem.
          examples:
            - https://example.com/error-log/abc123
          format: uri
          type: string
        status:
          description: HTTP status code
          examples:
            - 400
          format: int64
          type: integer
        title:
          description: >-
            A short, human-readable summary of the problem type. This value
            should not change between occurrences of the error.
          examples:
            - Bad Request
          type: string
        type:
          default: about:blank
          description: A URI reference to human-readable documentation for the error.
          examples:
            - https://example.com/errors/example
          format: uri
          type: string
        upstream:
          $ref: '#/components/schemas/Upstream'
          description: >-
            RFC 9457 extension member: the error a proxied third-party provider
            reported. Absent unless the emitting service explicitly surfaced
            one.
      required:
        - correlationId
      type: object
    PossessionEvidenceRequest:
      additionalProperties: false
      properties:
        challengeId:
          description: >-
            The client's own opaque handle on the verification — the SMS
            challenge, the e-mail confirmation, the onboarding case — so an
            auditor can find it in the system that performed the check. Opaque
            token only (letters, digits, . _ : -): never a tax id, a code, a key
            or a holder name.
          examples:
            - chg-8f2a1b
          maxLength: 128
          minLength: 6
          type: string
        method:
          description: >-
            How possession was verified, per section 2.1: SMS_CODE for a PHONE
            key and EMAIL_CODE for an EMAIL key (a code sent to the key itself
            and returned through an authenticated channel),
            ACCOUNT_OPENING_MATCH for a CPF or CNPJ key (the document offered as
            the key is the one the account was opened with). A method that
            cannot verify the key type it is offered for is rejected.
          enum:
            - SMS_CODE
            - EMAIL_CODE
            - ACCOUNT_OPENING_MATCH
          examples:
            - SMS_CODE
          type: string
        verifiedAt:
          description: >-
            When the client completed the verification, RFC 3339. Required: an
            attestation with no instant cannot be placed against the key's
            timeline. Never in the future. No method carries a recency ceiling —
            section 2.1 sets no freshness window — so state the instant the
            check actually happened, however old it is (an account-opening match
            is honestly as old as the account), never the present moment.
          examples:
            - '2026-08-19T12:00:00Z'
          format: date-time
          type: string
      required:
        - method
        - verifiedAt
        - challengeId
      type: object
    BACENEnvelopeResponse:
      additionalProperties: false
      properties:
        correlationId:
          description: >-
            BACEN's own correlation identifier for its most recent interaction
            on this record — the wire value, distinct from any request-scoped
            echo.
          examples:
            - a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4
          type: string
        lastModified:
          description: >-
            BACEN's own LastModified for this resource (RFC 3339, UTC) — the
            version this response reflects; present only on the MED resources
            (infraction, refund, fraud marker, funds recovery).
          examples:
            - '2026-06-14T12:00:00Z'
          type: string
        responseTime:
          description: >-
            Instant BACEN answered its most recent interaction on this record,
            RFC 3339 (UTC); omitted when BACEN's response carried no parseable
            instant.
          examples:
            - '2026-06-14T12:00:00Z'
          type: string
      required:
        - correlationId
      type: object
    ErrorDetail:
      additionalProperties: false
      properties:
        location:
          description: >-
            Where the error occurred, e.g. 'body.items[3].tags' or
            'path.thing-id'
          type: string
        message:
          description: Error message text
          type: string
        value:
          description: The value at the given location
      type: object
    Upstream:
      additionalProperties: false
      properties:
        code:
          description: The upstream provider's own error code, verbatim.
          examples:
            - E4001
          type: string
        message:
          description: >-
            The upstream provider's own error message, verbatim (bounded, never
            its raw response body).
          examples:
            - account not found at provider
          type: string
      type: object
  securitySchemes:
    BearerAuth:
      bearerFormat: JWT
      description: JWT bearer token issued by the identity provider.
      scheme: bearer
      type: http

````

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