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

# Abandon one unreadable record on a DICT poll feed

> Permanently gives up on ONE record BACEN serves that this deployment cannot read or store, so the feed can move past it. A DICT poll feed holds its position on such a record rather than passing it by silently, which is correct and has no other ending: clearing the feed's blocked marker resumes the walk at the same position and it stops again on the same record. This route is the human decision that ends that loop, and it is deliberately not the unblock route with a flag — unblocking says try again, this says give up on this one. It is refused for a caller with no identifiable principal, requires a reason, and writes an audit row naming who, which record and why. The record then stays listed on GET /api/v1/dict/discovery-feeds forever: an abandonment that ages out of a log is exactly the silent loss this verb exists to avoid. Only the named record is passed; every other held record still holds the feed. Idempotent — re-sending the same record is a no-op that is still audited. The write-off list is bounded per feed and is never trimmed to make room: at the limit this route refuses with 409 and says so plainly, because that many records given up on one feed is a systemic refusal rather than that many accidents. GET /api/v1/dict/discovery-feeds reports abandonedRecordsRemaining on every feed, and the brspi_dict_feed_abandoned_records_remaining gauge carries the same number, so the limit is visible long before it is met.



## OpenAPI

````yaml /en/openapi/v3-current/spi-dict.yaml post /api/v1/dict/discovery-feeds/{feed}/abandon-record
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/{feed}/abandon-record:
    post:
      tags:
        - Operations
      summary: Abandon one unreadable record on a DICT poll feed
      description: >-
        Permanently gives up on ONE record BACEN serves that this deployment
        cannot read or store, so the feed can move past it. A DICT poll feed
        holds its position on such a record rather than passing it by silently,
        which is correct and has no other ending: clearing the feed's blocked
        marker resumes the walk at the same position and it stops again on the
        same record. This route is the human decision that ends that loop, and
        it is deliberately not the unblock route with a flag — unblocking says
        try again, this says give up on this one. It is refused for a caller
        with no identifiable principal, requires a reason, and writes an audit
        row naming who, which record and why. The record then stays listed on
        GET /api/v1/dict/discovery-feeds forever: an abandonment that ages out
        of a log is exactly the silent loss this verb exists to avoid. Only the
        named record is passed; every other held record still holds the feed.
        Idempotent — re-sending the same record is a no-op that is still
        audited. The write-off list is bounded per feed and is never trimmed to
        make room: at the limit this route refuses with 409 and says so plainly,
        because that many records given up on one feed is a systemic refusal
        rather than that many accidents. GET /api/v1/dict/discovery-feeds
        reports abandonedRecordsRemaining on every feed, and the
        brspi_dict_feed_abandoned_records_remaining gauge carries the same
        number, so the limit is visible long before it is met.
      operationId: abandonDICTDiscoveryFeedRecord
      parameters:
        - description: Feed name exactly as GET /api/v1/dict/discovery-feeds reports it.
          in: path
          name: feed
          required: true
          schema:
            description: Feed name exactly as GET /api/v1/dict/discovery-feeds reports it.
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AbandonDICTFeedRecordRequest'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AbandonDICTFeedRecordResponse'
          description: OK
        '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
        '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:
    AbandonDICTFeedRecordRequest:
      additionalProperties: false
      properties:
        bacenRecordId:
          description: >-
            The record to abandon, exactly as GET /api/v1/dict/discovery-feeds
            reports it in heldBacenRecordIds. Two shapes appear there: a BACEN
            resource UUID this deployment permanently refuses, and the raw
            identifier BACEN sent for an entry whose id is not a UUID at all.
            Both are accepted verbatim; neither is interpreted.
          type: string
        reason:
          description: >-
            Why this regulated record is being given up. It is recorded in the
            audit trail under the caller's identity and is the only durable
            answer to 'why does this deployment not hold that record'. Operator
            prose only — never a tax id, a Pix key, an account or a holder name.
          maxLength: 384
          minLength: 8
          type: string
      required:
        - bacenRecordId
        - reason
      type: object
    AbandonDICTFeedRecordResponse:
      additionalProperties: false
      properties:
        abandonedRecords:
          description: How many records are now permanently abandoned on this feed.
          examples:
            - 1
          format: int64
          type: integer
        alreadyAbandoned:
          description: >-
            True when this record had already been abandoned. The call is then a
            no-op on the ledger, still audited under the caller's identity —
            re-sending the same request is safe.
          type: boolean
        bacenRecordId:
          description: The record, as supplied.
          type: string
        feed:
          description: The feed the record was abandoned on.
          examples:
            - dict_infraction_discovery
          type: string
        stillHeldBacenRecordIds:
          description: >-
            The records this feed was still stuck on when this call read the
            list, minus the one just abandoned. Empty means the next tick can
            move — unless the feed also carries a durable blocked marker, which
            is cleared separately on POST .../{feed}/unblock. A walk tick
            running alongside this call may already have found more; GET
            /api/v1/dict/discovery-feeds is always the current list.
          items:
            type: string
          type: array
        warning:
          description: >-
            States plainly that the record is now permanently absent from this
            deployment.
          type: string
      required:
        - feed
        - bacenRecordId
        - abandonedRecords
        - warning
      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

````