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

# Approve a proposal

> Records one approval. The card is promoted, and the proposal becomes `approved`, only
when `approvalsReceived` reaches `approvalsRequired`; below quorum the response is still
`accepted` and the proposal stays `needs_human`. One approval per reviewer; authors
cannot act on their own proposals. **Dashboard session only.**




## OpenAPI

````yaml /openapi/zebratruth-v1.yaml post /memory/review-queue/{proposalId}/approve
openapi: 3.1.0
info:
  title: ZebraTruth Compliance API
  version: 1.0.0
  description: >
    AI-powered compliance checking for advertising content. Check text and
    images against

    jurisdiction laws, platform policies, and rights clearance requirements.
    Results include

    embeddable annotations mapped to content locations (text spans, video
    timestamps, image regions).
  contact:
    name: ZebraTruth Support
    email: support@zebratruth.ai
    url: https://developers.zebratruth.ai
  license:
    name: MIT
    url: https://opensource.org/licenses/MIT
servers:
  - url: https://api.zebratruth.ai/v1
    description: Production
security:
  - bearerAuth: []
tags:
  - name: Video Compliance
    description: >
      **Primary endpoint.** Async compliance analysis for video ads. 3-step
      flow:

      get an upload URL, upload the video bytes, submit for analysis. Poll or

      receive an HMAC-signed webhook with the report. Returns timestamped

      findings citing stable evidence IDs (`audio_NNN`, `frame_NNN`, `ocr_NNN`,

      `signal_NNN`). 3-180 second videos. mp4 / webm /

      quicktime. Built for ad agencies and creators.
  - name: Authentication
    description: Validate API keys and check account status
  - name: Compliance
    description: >-
      Run compliance checks on text + image content (sync). For video, use the
      Video Compliance endpoints above.
  - name: Agents
    description: Discover and invoke individual compliance agents
  - name: Jobs
    description: Poll async job status and view execution traces
  - name: Reports
    description: Retrieve and replay compliance reports
  - name: Observability
    description: Request logs and webhook delivery status
  - name: Billing
    description: Subscriptions, plan changes, and credit balance
  - name: Documents
    description: Extract text from PDF and Word documents before or as part of a check
  - name: Check History
    description: List and retrieve past compliance checks for the workspace
  - name: Provenance
    description: Inspect and sign Content Credentials (C2PA) on images and video
  - name: Corpus
    description: >-
      Review queue for proposed changes to the governed legal corpus (dashboard
      session)
  - name: Webhooks
    description: Saved webhook endpoints (dashboard session) and delivery logs
paths:
  /memory/review-queue/{proposalId}/approve:
    post:
      tags:
        - Corpus
      summary: Approve a proposal
      description: >
        Records one approval. The card is promoted, and the proposal becomes
        `approved`, only

        when `approvalsReceived` reaches `approvalsRequired`; below quorum the
        response is still

        `accepted` and the proposal stays `needs_human`. One approval per
        reviewer; authors

        cannot act on their own proposals. **Dashboard session only.**
      operationId: approveProposal
      parameters:
        - name: proposalId
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ReviewActionRequest'
      responses:
        '200':
          description: Accepted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReviewActionResponse'
        '403':
          description: Not authorised for this proposal's scope, role, or authorship.
        '404':
          description: Proposal not found.
        '409':
          description: >-
            The packet is stale or the proposal has moved on. Re-read the packet
            at `refreshUrl`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReviewActionConflict'
        '422':
          description: >-
            `data.code`: `MEMORY_IDEMPOTENCY_KEY_REQUIRED`,
            `MEMORY_IDEMPOTENCY_KEY_INVALID`, or a schema failure.
components:
  schemas:
    ReviewActionRequest:
      type: object
      required:
        - packetEtag
        - idempotencyKey
      properties:
        packetEtag:
          type: string
          description: >-
            The `packetEtag` from the packet you reviewed. A stale value is
            refused with 409 `stale_packet_etag`.
        idempotencyKey:
          type: string
          minLength: 8
          maxLength: 128
          pattern: ^[A-Za-z0-9.-]+$
        note:
          type: string
          description: Optional on approve; required on reject and request_changes.
        reasonCode:
          type: string
          description: Required on reject.
        requestedFields:
          type: array
          items:
            type: string
          description: Optional on request_changes.
    ReviewActionResponse:
      type: object
      properties:
        action:
          type: string
          enum:
            - approve
            - reject
            - request_changes
        proposalId:
          type: string
        status:
          type: string
          enum:
            - accepted
        idempotencyKey:
          type: string
        packetEtag:
          type: string
          description: The packet's etag after this action.
    ReviewActionConflict:
      type: object
      properties:
        error:
          type: string
          enum:
            - conflict
        code:
          type: string
          enum:
            - stale_packet_etag
            - proposal_already_acted
            - conflict_changed
            - idempotency_in_flight
            - idempotency_conflict
            - already_approved_by_reviewer
            - conflict_already_resolved_to_different_winner
        message:
          type: string
        proposalId:
          type: string
        currentPacketEtag:
          type: string
        refreshUrl:
          type: string
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: |
        API key starting with `zt_live_` (production) or `zt_test_` (sandbox).
        Get your key at https://developers.zebratruth.ai

````

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