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

# `GET /v1/audit/{alert_id}` — single receipt with ADR-0006 four-state
discrimination.

> Returns `Response` (not `Json`) so each status path can carry distinct
headers and body without fighting axum's `Result<T, E>` → IntoResponse
conversion (which forces non-2xx into the `Err` arm).



## OpenAPI

````yaml https://api.pegana.xyz/openapi.json get /v1/audit/{alert_id}
openapi: 3.1.0
info:
  title: Pegana API
  description: >-
    The peg-risk oracle for Solana. Read real-time peg state, history, alerts,
    and delivery health across 26 active mainnet assets spanning 6 classes —
    LSTs, fiat / CDP / delta-neutral / yield-bearing / FX stables, and a
    leveraged synthetic. Some assets are flagged `monitoring_only` (beta): their
    alerts are live but the calibration is provisional. Public read endpoints
    require no API key but ARE rate-limited per IP (300/min global, 10/min on
    /v1/audit.csv); exceeding the limit returns 429 with a Retry-After header.
    User-scoped /v1/me/* routes require a JWT obtained via Telegram Login. Every
    state transition emits a public receipt at /v1/audit/{id} with the
    methodology version, frozen inputs, and an on-chain SPL Memo commit (SAS
    deferred per ADR-0004 — SPL Memo gives 90% of the value). EVERY error
    response across the API is JSON — the envelope is `{error, message, asset?}`
    (the `ApiError` schema); branch on the stable `error` code, never on
    `message`. Malformed request bodies surface as `{error:"invalid_body"}`. Any
    endpoint may also return 500 `{error:"internal"}` on an unexpected server
    error.
  contact:
    name: Rafael Souza
    email: raffxweb3@gmail.com
  license:
    name: MIT
    identifier: MIT
  version: 0.1.0
servers:
  - url: https://api.pegana.xyz
    description: Production
security: []
tags:
  - name: Health
    description: Liveness and readiness probes
  - name: Assets
    description: Public read access to asset state, history, and metadata
  - name: Alerts
    description: Global feed of state transitions
  - name: Stats
    description: Aggregate counters and delivery health
  - name: Auth
    description: Telegram Login Widget → JWT
  - name: Me
    description: Authenticated user profile and preferences
  - name: Subscriptions
    description: User alert subscriptions
  - name: Webhooks
    description: User-managed Ed25519-signed webhooks
  - name: WebSocket
    description: Live state stream
  - name: audit
    description: >-
      Public receipts for alerts — methodology version, inputs frozen, replay
      bundles. All endpoints public, no auth, cacheable. ADR-0006 four-state
      response on /v1/audit/:id (200/202/404/410); ADR-0014 bounds (90-day max,
      100-row max, 50k-row cap).
  - name: methodology
    description: >-
      Public lifecycle status of the active methodology — version + status
      (active/deprecated/broken) + optional fix_url when broken. Consumed by
      web/app/api/methodology to power the home-page trust strip.
  - name: peg
    description: >-
      Mint-keyed peg-signal feed for tokens.xyz / aggregator consumption.
      Public, no auth, cacheable. Honest beta status via `calibration` +
      `monitoring_only`; freshness via `as_of` + `stale`.
paths:
  /v1/audit/{alert_id}:
    get:
      tags:
        - audit
      summary: |-
        `GET /v1/audit/{alert_id}` — single receipt with ADR-0006 four-state
        discrimination.
      description: |-
        Returns `Response` (not `Json`) so each status path can carry distinct
        headers and body without fighting axum's `Result<T, E>` → IntoResponse
        conversion (which forces non-2xx into the `Err` arm).
      operationId: audit_detail
      parameters:
        - name: alert_id
          in: path
          description: Alert UUID
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Receipt JSON (alert + evidence wrapper)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AuditDetailResponse'
        '202':
          description: >-
            Evidence persistence pending (ADR-0006); body carries
            retry_after_seconds
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AuditPendingResponse'
        '400':
          description: Invalid UUID format
        '404':
          description: >-
            Unknown alert_id (no row in alert_evidence or
            alert_evidence_pending)
        '410':
          description: >-
            Evidence persistence failed permanently (ADR-0006); receipt will
            never materialize
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AuditGoneResponse'
components:
  schemas:
    AuditDetailResponse:
      type: object
      description: >-
        Receipt envelope returned by `GET /v1/audit/{alert_id}` with a 200 (the

        `alert_evidence` row exists). The runtime body is assembled via `json!`
        for

        LEFT-JOIN flexibility; these structs mirror it field-for-field so

        `/openapi.json` documents the REAL shape instead of two opaque objects.
        Kept

        in lockstep with the `json!` body manually — the 202/410 responses use a

        different shape (see the endpoint's other documented responses).
      required:
        - alert
        - evidence
        - evidence_status
      properties:
        alert:
          $ref: '#/components/schemas/AuditAlert'
        evidence:
          $ref: '#/components/schemas/AuditEvidence'
        evidence_status:
          type: string
          description: Always `"ready"` on a 200.
    AuditPendingResponse:
      type: object
      description: |-
        202 body for `GET /v1/audit/{alert_id}` — receipt persistence is still
        retrying (ADR-0006). Poll again after `retry_after_seconds`.
      required:
        - status
        - alert_id
        - alert_dispatched_at
        - retry_after_seconds
        - evidence_status
      properties:
        alert_dispatched_at:
          type: string
          format: date-time
          description: When the alert was dispatched (the dead-letter `queued_at`).
        alert_id:
          type: string
        evidence_status:
          type: string
          description: Always `"pending"`.
        retry_after_seconds:
          type: integer
          format: int64
          description: Suggested back-off before re-polling.
        status:
          type: string
          description: Always `"pending"`.
    AuditGoneResponse:
      type: object
      description: >-
        410 body for `GET /v1/audit/{alert_id}` — receipt persistence failed

        permanently (ADR-0006 dead-letter terminal); the receipt will never
        land.
      required:
        - status
        - alert_id
        - alert_dispatched_at
        - evidence_status
      properties:
        alert_dispatched_at:
          type: string
          format: date-time
          description: When the alert was dispatched (the dead-letter `queued_at`).
        alert_id:
          type: string
        evidence_status:
          type: string
          description: Always `"failed_permanent"`.
        last_error:
          type:
            - string
            - 'null'
          description: Last persistence error recorded, if any.
        status:
          type: string
          description: Always `"persistence_failed"`.
    AuditAlert:
      type: object
      description: >-
        The `alert` object inside a 200 receipt body (`GET
        /v1/audit/{alert_id}`).

        Decimal money fields are JSON strings (preserves precision).
      required:
        - id
        - asset
        - class
        - from_state
        - to_state
        - discount
        - intrinsic_usd
        - market_usd
        - confidence
        - detected_at
      properties:
        asset:
          type: string
        class:
          type: string
        confidence:
          $ref: '#/components/schemas/Confidence'
        detected_at:
          type: string
          format: date-time
        discount:
          type: string
          description: Signed discount fraction at detection, as a decimal string.
        from_state:
          $ref: '#/components/schemas/PegState'
        id:
          type: string
          description: Alert UUID.
        intrinsic_usd:
          type: string
        market_usd:
          type: string
        to_state:
          $ref: '#/components/schemas/PegState'
    AuditEvidence:
      type: object
      description: |-
        The `evidence` object inside a 200 receipt body — the frozen inputs and
        methodology pin that make the alert independently verifiable.
      required:
        - methodology_version
        - assets_toml_sha256
        - inputs_frozen
        - computed
        - has_replay_artifact
        - receipt_sha256
        - created_at
      properties:
        assets_toml_sha256:
          type: string
        commit_status:
          type:
            - string
            - 'null'
          description: >-
            `not_applicable` | `pending` | `committed` | `retry_exhausted` |
            `wallet_drained`.
        computed:
          description: Verbatim computed intermediates.
        created_at:
          type: string
          format: date-time
        has_replay_artifact:
          type: boolean
        inputs_frozen:
          description: >-
            Verbatim frozen inputs snapshot (shape depends on methodology
            version).
        methodology_git_sha:
          type:
            - string
            - 'null'
        methodology_version:
          type: string
        onchain_tx_sig:
          type:
            - string
            - 'null'
        receipt_sha256:
          type: string
    Confidence:
      type: string
      description: >-
        Pyth oracle confidence bucket. Mirrors `pyth_confidence_label`. Scopes
        the

        PRICE-ORACLE confidence interval only (conf/price ratio) — NOT
        market-quote

        or route-depth reliability.
      enum:
        - high
        - medium
        - low
        - unknown
    PegState:
      type: string
      description: >-
        Class-aware peg state. Mirrors the engine `PegState` enum and the

        `peg_state` Postgres enum. Used for `state`, `from_state`, and
        `to_state`

        fields across the API.


        The state is CLASS-AWARE: an LST reading a −1.4% discount (normal
        unstaking

        spread) is `PEGGED`, while a fiat stable at far less would be `DRIFT`.
        Trust

        this value directly rather than imposing a naive discount cut.
      enum:
        - PEGGED
        - DRIFT
        - DEPEG
        - CRITICAL
        - BLACK_SWAN
        - UNKNOWN

````