> ## 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.

# Watch a CPF/CNPJ for antifraud signal

> Admits a document to the antifraud watchlist. Once watched, BACEN's ecosystem-wide antifraud counters for that document (getPersonStatistics) are observed on a configured cadence, and a canonical observation fact is emitted whenever BACEN's own watermark moves. Idempotent: re-adding a watched document changes nothing; re-adding a removed one resumes it with its dedupe baseline intact. Rejected with 422 once the participant's document cap is reached, because every watched document is a recurring call against a shared BACEN budget.



## OpenAPI

````yaml /es/openapi/v3-current/spi-dict.yaml post /api/v1/dict/persons/watchlist
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://spi.sandbox.lerian.net
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: >-
      Internal DICT operations: reconciliation runs, claim deadline processing,
      and orphaned-key cleanup.
    name: Internal
paths:
  /api/v1/dict/persons/watchlist:
    post:
      tags:
        - Statistics
      summary: Watch a CPF/CNPJ for antifraud signal
      description: >-
        Admits a document to the antifraud watchlist. Once watched, BACEN's
        ecosystem-wide antifraud counters for that document
        (getPersonStatistics) are observed on a configured cadence, and a
        canonical observation fact is emitted whenever BACEN's own watermark
        moves. Idempotent: re-adding a watched document changes nothing;
        re-adding a removed one resumes it with its dedupe baseline intact.
        Rejected with 422 once the participant's document cap is reached,
        because every watched document is a recurring call against a shared
        BACEN budget.
      operationId: addPersonWatchlistDocument
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PersonWatchlistAddRequest'
        required: true
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PersonWatchlistEntryResponse'
          description: Created
        '422':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Detail'
          description: Unprocessable Entity
        '500':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Detail'
          description: Internal Server Error
        default:
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Detail'
          description: Error
      security:
        - BearerAuth: []
components:
  schemas:
    PersonWatchlistAddRequest:
      additionalProperties: false
      properties:
        taxIdNumber:
          description: >-
            CPF (11 digits) or CNPJ (14 characters — alphanumeric since IN RFB
            2.229/2024) to watch. Sent in the body, never in the URL, because it
            is PII. Re-adding a document already watched returns the existing
            entry unchanged; re-adding one previously removed resumes watching
            the same entry, preserving its last observation.
          type: string
      required:
        - taxIdNumber
      type: object
    PersonWatchlistEntryResponse:
      additionalProperties: false
      properties:
        consecutiveFailures:
          description: >-
            How many observation attempts have failed back to back. Any success
            resets it to zero.
          format: int64
          type: integer
        createdAt:
          description: When the document was admitted (RFC 3339).
          type: string
        id:
          description: Opaque entry id. Remove addresses this, never the document.
          format: uuid
          type: string
        lastAttemptAt:
          description: >-
            When the poll last TRIED this document, successfully or not.
            Diverging from lastObservedAt means BACEN is refusing this subject.
          type: string
        lastObservedAt:
          description: >-
            When BACEN's counters were last read for this document. Absent until
            the first observation.
          type: string
        lastWatermark:
          description: >-
            BACEN's own freshness marker for the last observation — the
            composite of the four PersonStatistics block watermarks. This, not
            the read time, is what changes when the counters change. BACEN's
            counters are up to 12 hours stale by regulation, so a recent read
            never means recent data.
          type: string
        quarantinedAt:
          description: >-
            When repeated failures parked this document. A parked document is no
            longer polled and no longer counted by the readiness staleness check
            — one unreadable subject must not take the rail unready. Removing
            and re-adding it resumes surveillance.
          type: string
        removedAt:
          description: >-
            When surveillance was stopped, if it was. Removal is a soft stop:
            observations already emitted are never retracted.
          type: string
        taxIdNumber:
          description: The watched CPF/CNPJ.
          type: string
      required:
        - id
        - taxIdNumber
        - createdAt
        - consecutiveFailures
      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
    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

````