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

# GetApprovalAPI mirrors erdo_get_approval: one request in full, the read a


> decision is made against — the itemized projection, the recorded reason, and the scope options — where the list is sized for scanning.




## OpenAPI

````yaml /api/openapi.json get /v1/approvals/{id}
openapi: 3.0.0
info:
  title: Erdo API
  description: >-
    Erdo's REST API: query and write datasets, run agents, manage threads,
    integrations, pages, evals, workstreams, and experiments. Authenticate with
    a Bearer API key (erdo_api_...) or scoped token (erdo_token_...).
  version: '2026-08-07'
servers:
  - url: https://api.erdo.ai
    description: Production
security:
  - bearerAuth: []
paths:
  /v1/approvals/{id}:
    get:
      summary: >
        GetApprovalAPI mirrors erdo_get_approval: one request in full, the read
        a
      description: >
        decision is made against — the itemized projection, the recorded reason,
        and the scope options — where the list is sized for scanning.
      operationId: GET:mcp.GetApprovalAPI
      parameters:
        - allowEmptyValue: true
          explode: false
          in: path
          name: id
          required: true
          schema:
            type: string
          style: simple
      responses:
        '200':
          content:
            application/json:
              schema:
                properties:
                  action_context:
                    type: string
                  action_display:
                    type: string
                  action_headline:
                    type: string
                  action_input:
                    type: object
                  action_items:
                    items:
                      $ref: '#/components/schemas/types.ApprovalActionItem'
                    type: array
                  action_key:
                    type: string
                  agent_run_id:
                    format: uuid
                    type: string
                  card_contract_version:
                    description: >
                      service from the stored row and the action registry, never
                      by a consumer. See ApprovalCard for what each field
                      promises; CardContractVersion is what a renderer keys its
                      expectations on.
                    title: >
                      The derived card projection — everything below is computed
                      by the approval
                    type: string
                  created_at:
                    format: date-time
                    type: string
                  decided_at:
                    format: date-time
                    type: string
                  decided_by_user_id:
                    format: uuid
                    type: string
                  decision_class:
                    type: string
                  decision_parameter_constraints:
                    type: object
                  decision_scope:
                    type: string
                  expected_effect:
                    description: >
                      captured at filing from the call's expected\_effect field
                      and stored verbatim — the approval service never
                      interprets it. The decision record turns it into a typed
                      measurement contract when it records the decision this
                      approval became; see ExpectedEffect for the declaration's
                      shape.


                      Absent on most approvals, and honestly so: a change with
                      no measurable business effect is better declaring nothing
                      than inventing a metric.
                    title: >
                      ExpectedEffect is what the proposing producer said this
                      change would move,
                    type: object
                  expires_at:
                    description: >
                      report is moot the next day). nil is the default and the
                      common case — an ask with no deadline never ages out; it
                      resolves only when decided, superseded, or withdrawn.
                    format: date-time
                    title: >
                      ExpiresAt is set only when the action declared a SEMANTIC
                      deadline (a daily
                    type: string
                  first_proposed_at:
                    format: date-time
                    type: string
                  id:
                    format: uuid
                    type: string
                  job_execution_id:
                    format: uuid
                    type: string
                  job_id:
                    format: uuid
                    type: string
                  last_proposed_at:
                    format: date-time
                    type: string
                  occurrence_count:
                    format: int64
                    type: integer
                  omitted_items:
                    format: int64
                    type: integer
                  organization_id:
                    format: uuid
                    type: string
                  scope_options:
                    items:
                      $ref: '#/components/schemas/types.ScopeOption'
                    type: array
                  status:
                    type: string
                  subject_display_name:
                    type: string
                  subject_key:
                    description: >
                      deduplication. OccurrenceCount is how many times this
                      exact action-on-subject has been proposed (1 = proposed
                      once); when > 1 the UI shows "proposed Nx since
                      \<FirstProposedAt>". FirstProposedAt/LastProposedAt
                      COALESCE to CreatedAt when the row predates dedupe
                      tracking.
                    title: >
                      SubjectKey / OccurrenceCount / FirstProposedAt /
                      LastProposedAt surface
                    type: string
                  subject_resource_id:
                    type: string
                  subject_resource_type:
                    description: >
                      acts on (e.g. "artifact" + its id), when the action's
                      registration declares one. They let a client resolve and
                      render the actual subject — open/preview the page being
                      published — instead of parsing a display string. Empty
                      when the action carries no resolvable subject.
                    title: >
                      SubjectResourceType / SubjectResourceID are the typed
                      resource this approval
                    type: string
                  supersedes_decision_slug:
                    description: >
                      this action would end, captured at filing from the call's
                      supersedes\_decision\_slug field. Stored as its own column
                      rather than left in action\_input because the decision
                      producer must read it after the human answers, and a
                      re-proposal rewrites that blob wholesale.


                      Empty on almost every approval: most changes reverse
                      nothing.
                    title: >
                      SupersedesDecisionSlug is the standing decision the
                      proposing agent said
                    type: string
                  thread_id:
                    format: uuid
                    type: string
                  workstream_id:
                    format: uuid
                    type: string
                type: object
          description: Success response
        default:
          $ref: '#/components/responses/APIError'
components:
  schemas:
    types.ApprovalActionItem:
      description: >
        what an approver needs to judge it: WHAT it does (the resolved display),
        WHY it was proposed (the producer's declared reason), the business class
        of the decision, and the handful of parameters the action's own
        registration declared safe to surface. A single-action approval has
        exactly one item; a batch has one per child, ordered by the same (class,
        intent) grouping the batch's display describes it in.


        Every field is bounded and derived — this is deliberately NOT the raw
        action input. Generic card code never guesses which of a provider's
        fields matter, so an action that declares no projection ships an item
        with no params rather than a dump of its payload.
      properties:
        decision_class:
          type: string
        params_compact:
          additionalProperties:
            type: string
          type: object
        what:
          type: string
        why:
          type: string
      title: >
        ApprovalActionItem is one exact action inside an approval, projected
        down to
      type: object
    types.ScopeOption:
      description: >
        Generated by the backend so the frontend doesn't guess which params
        matter.
      properties:
        constraints:
          additionalProperties:
            $ref: '#/components/schemas/types.ParameterConstraint'
          title: |
            policy constraints to create
          type: object
        label:
          title: |
            e.g. "Send Email where to = niall@erdo.ai"
          type: string
      title: >
        ScopeOption is a pre-computed "always approve" option sent to the
        frontend.
      type: object
    types.ParameterConstraint:
      properties:
        pattern:
          title: |
            glob pattern for strings
          type: string
        values:
          items:
            type: string
          title: |
            allowed values list
          type: array
      title: |
        ParameterConstraint defines a constraint on a tool input parameter.
      type: object
  responses:
    APIError:
      content:
        application/json:
          schema:
            externalDocs:
              url: https://pkg.go.dev/encore.dev/beta/errs#Error
            properties:
              code:
                description: Error code
                example: not_found
                externalDocs:
                  url: https://pkg.go.dev/encore.dev/beta/errs#ErrCode
                type: string
              details:
                description: Error details
                type: object
              message:
                description: Error message
                type: string
            title: APIError
            type: object
      description: Error response
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: An Erdo API key (erdo_api_...) or scoped token (erdo_token_...).

````