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

# List DICT poll feed states

> Reports which DICT poll feeds (claim discovery, MED infraction/refund discovery, the fraud-marker inventory sweep, funds-recovery event notifications) are frozen on a durable blocked marker, with the closed-vocabulary reason and the instant the freeze started. It also reports the funds-recovery feed's replay list: BACEN records it permanently stepped over and never stored, named by BACEN resource id, which are replayed through POST /api/v1/dict/funds-recoveries/intake. It also names the records a feed is currently stuck on and the ones a named operator has permanently abandoned: a held record listed here is the id an operator supplies to POST /api/v1/dict/discovery-feeds/{feed}/abandon-record, which is how a walk pinned on a record this deployment can never store is made to move on. A frozen feed deliberately does NOT degrade readiness — this rail also serves Pix keys, entries and claims, and the routes an operator needs to resolve a freeze are served by the same replicas — so this route, the brspi_dict_feed_blocked gauge and the operational event are the alarm.



## OpenAPI

````yaml /es/openapi/v3-current/spi-dict.yaml get /api/v1/dict/discovery-feeds
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/discovery-feeds:
    get:
      tags:
        - Operations
      summary: List DICT poll feed states
      description: >-
        Reports which DICT poll feeds (claim discovery, MED infraction/refund
        discovery, the fraud-marker inventory sweep, funds-recovery event
        notifications) are frozen on a durable blocked marker, with the
        closed-vocabulary reason and the instant the freeze started. It also
        reports the funds-recovery feed's replay list: BACEN records it
        permanently stepped over and never stored, named by BACEN resource id,
        which are replayed through POST /api/v1/dict/funds-recoveries/intake. It
        also names the records a feed is currently stuck on and the ones a named
        operator has permanently abandoned: a held record listed here is the id
        an operator supplies to POST
        /api/v1/dict/discovery-feeds/{feed}/abandon-record, which is how a walk
        pinned on a record this deployment can never store is made to move on. A
        frozen feed deliberately does NOT degrade readiness — this rail also
        serves Pix keys, entries and claims, and the routes an operator needs to
        resolve a freeze are served by the same replicas — so this route, the
        brspi_dict_feed_blocked gauge and the operational event are the alarm.
      operationId: listDICTDiscoveryFeeds
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DICTDiscoveryFeedListResponse'
                description: State of every DICT poll feed that can freeze.
          description: OK
        '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:
    DICTDiscoveryFeedListResponse:
      additionalProperties: false
      properties:
        abandonedCount:
          description: >-
            How many regulated records named operators have abandoned across all
            listed feeds. Permanent.
          examples:
            - 0
          format: int64
          type: integer
        blockedCount:
          description: How many of the listed feeds are currently frozen.
          examples:
            - 0
          format: int64
          type: integer
        heldCount:
          description: >-
            How many of the listed feeds are running but not covering everything
            — pinned on a record this deployment permanently refuses, on an
            entry whose BACEN resource id could not be read, or (the
            fraud-marker sweep) on a window left edge that stopped advancing.
            Each one names what it is stuck on in heldBacenRecordIds.
          examples:
            - 0
          format: int64
          type: integer
        items:
          description: Every DICT poll feed that can freeze, blocked or not.
          items:
            $ref: '#/components/schemas/DICTDiscoveryFeedResponse'
          type: array
        steppedOverCount:
          description: >-
            How many of the listed feeds carry BACEN records they permanently
            stepped over and never stored, awaiting replay.
          examples:
            - 0
          format: int64
          type: integer
      required:
        - items
        - blockedCount
        - heldCount
        - steppedOverCount
        - abandonedCount
      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
    DICTDiscoveryFeedResponse:
      additionalProperties: false
      properties:
        abandonedBacenRecordIds:
          description: >-
            The abandoned records, oldest first. Permanent: nothing in this
            service removes an entry, so an abandonment stays visible long after
            the log line that recorded it is gone. Who abandoned each one, and
            why, is in the audit trail.
          items:
            type: string
          type:
            - array
            - 'null'
        abandonedRecords:
          description: >-
            How many regulated records a named operator has permanently
            abandoned on this feed. The walk moves past exactly these records
            and no others; this deployment will never hold them.
          examples:
            - 1
          format: int64
          type: integer
        abandonedRecordsLimit:
          description: >-
            How many records may ever be written off on one feed. Fixed, and
            deliberately not raised to make a refusal go away: reaching it means
            a human personally gave up on this many regulated records on this
            one feed, which is a systemic refusal rather than that many
            accidents.
          examples:
            - 500
          format: int64
          type: integer
        abandonedRecordsRemaining:
          description: >-
            How many more records may be written off on this feed before POST
            /api/v1/dict/discovery-feeds/{feed}/abandon-record refuses. Zero
            means a record this feed is held on has no in-band ending left: it
            stays held and stays listed, the feed stays pinned on it, and the
            way out is to resolve what makes those records unstorable or to
            raise them with BACEN. The gauge
            brspi_dict_feed_abandoned_records_remaining carries the same number
            for alerting. It is a budget for the write-off, not a promise that
            this feed's current hold can use one: a feed held under
            window_left_edge_held or participant_not_served lists no record, so
            there is nothing to spend it on however many remain. Always 500 on
            dict_funds_recovery_events, which steps records over instead of
            holding them and has no write-off at all.
          examples:
            - 500
          format: int64
          type: integer
        abandonedSince:
          description: >-
            When the abandoned list last grew (RFC 3339, UTC); absent when it is
            empty.
          examples:
            - '2026-08-14T09:00:00Z'
          type: string
        blocked:
          description: >-
            True while the feed is frozen on its durable blocked marker. A
            frozen feed discovers nothing and does not clear on restart;
            readiness deliberately stays up so this deployment's operator routes
            remain reachable.
          examples:
            - false
          type: boolean
        blockedSince:
          description: >-
            When the freeze started (RFC 3339, UTC); absent when the feed is
            running.
          examples:
            - '2026-08-13T12:00:00Z'
          type: string
        feed:
          description: >-
            Feed name — the same string as the feed's blocked gauge, refusal
            counters and operational events, so every operator surface names a
            feed identically. It matches the feed's /readyz check name for the
            MED discovery and fraud-marker feeds; the two claim feeds share one
            readiness leg (dict_claim_feed_pagination) and so do not.
          examples:
            - dict_infraction_discovery
          type: string
        held:
          description: >-
            True while the feed's window is pinned and it is not covering
            everything: it sits on a record this deployment permanently refuses
            (record_quarantined), or on an entry whose BACEN resource id could
            not be read at all (malformed_entry_unreadable), or the fraud-marker
            sweep closed a cycle without covering it so its window's left edge
            stays where it is (window_left_edge_held), or BACEN served entries
            no participant this deployment serves is party to
            (participant_not_served), or the donor's receipt of an OPEN claim
            could not be sent and the window is pinned until it lands
            (claim_receipt_deferred), or that receipt is refused by a judicial
            block on the donor key and stays owed until the court order lifts
            (claim_receipt_blocked) — the one hold that does NOT pin the window,
            because an ofício lasts weeks and the receipt is written down and
            re-attempted every tick instead, so the feed goes on discovering
            while it stands. Distinct from blocked: a hold on its own freezes
            nothing, and the unblock route does not apply to it because there is
            no durable blocked marker to clear. A hold that survives the
            tolerated ticks becomes a block, and then both are true. Whether an
            operator has anything to abandon depends on WHICH hold it is, so
            read heldReason before reaching for the write-off:
            record_quarantined and malformed_entry_unreadable name their records
            in heldBacenRecordIds and the write-off is their sanctioned ending;
            claim_receipt_blocked names its claim too, but a court order lifts
            on its own and the tick after the lift sends the receipt, so the
            write-off is a last resort there, not the ending to reach for;
            window_left_edge_held, participant_not_served and
            claim_receipt_deferred name none and the write-off does not apply to
            them at all.
          examples:
            - false
          type: boolean
        heldBacenRecordIds:
          description: >-
            The records this feed is currently stuck on, oldest first: a BACEN
            resource id this deployment permanently refuses, the raw identifier
            BACEN sent for an entry whose id is not a UUID, or an 'unreadable-'
            handle standing in for an identifier too long or too strange to list
            verbatim. Anything listed here can be abandoned with POST
            /api/v1/dict/discovery-feeds/{feed}/abandon-record, and nothing else
            can — but read heldReason first: under claim_receipt_blocked the
            listed claim is one a judicial block postponed, its receipt is
            re-attempted on every tick without holding the feed up, and it is
            receivable again the day the ofício lifts with no operator action at
            all, so writing it off there discards a claim this deployment would
            otherwise have kept. Three holds list nothing at all and have no
            write-off: claim_receipt_deferred, whose next tick retries the
            receipt for free; window_left_edge_held, which is stuck on a watched
            document that is kept off this list and whose only lever is
            resetModifiedAfter on the unblock route once the hold has escalated
            to a block; and participant_not_served, which clears by itself as
            this deployment's participant registry catches up with BACEN and
            must never be written off. Otherwise capped per feed, so it can be
            shorter than heldEntries.
          items:
            type: string
          type:
            - array
            - 'null'
        heldEntries:
          description: >-
            How many entries the feed is stuck on. For a record this deployment
            permanently refuses it is how many such records are named in
            heldBacenRecordIds. For an entry whose BACEN resource id could not
            be read it is how many the feed could not read — the last tick, for
            the walks that stop at the first such page; the current CYCLE, for
            the fraud-marker sweep, whose cycle spans several sweeps of the
            book: it rises as those sweeps land and settles when the cycle
            closes. A document a run bound cut mid-walk counts on the sweep that
            finishes it, never on both. A book meeting the same unreadable entry
            cycle after cycle keeps reporting that one entry, and heldSince
            keeps answering how long it has been that way. Or, for that sweep's
            window hold, how many documents its last dirty cycle could not
            cover.
          examples:
            - 1
          format: int64
          type: integer
        heldReason:
          description: Closed-vocabulary reason the feed is pinned; absent when it is not.
          examples:
            - malformed_entry_unreadable
          type: string
        heldSince:
          description: >-
            When the held count last CHANGED (RFC 3339, UTC) — a tick that finds
            the same count does not re-stamp it, so this reads as how long the
            feed has been stuck on this many entries. Absent when the window is
            not pinned.
          examples:
            - '2026-08-13T12:00:00Z'
          type: string
        reason:
          description: >-
            Closed-vocabulary reason the feed froze; absent when the feed is
            running.
          examples:
            - inclusive_modified_after_no_progress
          type: string
        steppedOverBacenResourceIds:
          description: >-
            The BACEN resource ids awaiting replay, oldest first. Replay them
            with POST /api/v1/dict/funds-recoveries/intake, which runs the
            identical pipeline; attesting on that request clears both this list
            and the block it raised.
          items:
            type: string
          type:
            - array
            - 'null'
        steppedOverEntries:
          description: >-
            How many BACEN records this feed permanently stepped over and never
            stored, awaiting replay.
          examples:
            - 2
          format: int64
          type: integer
        steppedOverSince:
          description: >-
            When the replay list last grew (RFC 3339, UTC); absent when it is
            empty.
          examples:
            - '2026-08-13T12:00:00Z'
          type: string
        steppedOverUnlisted:
          description: >-
            How many stepped-over records this feed cannot name — BACEN's entity
            id was not a resource id, or the replay list was full when they
            arrived. They are missing exactly as the listed ones are, but cannot
            be replayed by id; raise them with BACEN. The intake attestation
            clears this count together with the list.
          examples:
            - 1
          format: int64
          type: integer
      required:
        - feed
        - blocked
        - held
        - abandonedRecordsLimit
        - abandonedRecordsRemaining
      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

````