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

# ListDecisionsAPI mirrors erdo_list_decisions.




## OpenAPI

````yaml /api/openapi.json get /v1/decisions
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/decisions:
    get:
      summary: |
        ListDecisionsAPI mirrors erdo_list_decisions.
      operationId: GET:mcp.ListDecisionsAPI
      parameters:
        - allowEmptyValue: true
          explode: true
          in: query
          name: workstream_slug
          required: false
          schema:
            type: string
          style: form
        - allowEmptyValue: true
          explode: true
          in: query
          name: source
          required: false
          schema:
            type: string
          style: form
        - allowEmptyValue: true
          explode: true
          in: query
          name: decision_class
          required: false
          schema:
            type: string
          style: form
        - allowEmptyValue: true
          explode: true
          in: query
          name: subject_kind
          required: false
          schema:
            type: string
          style: form
        - allowEmptyValue: true
          explode: true
          in: query
          name: subject_ref
          required: false
          schema:
            type: string
          style: form
        - allowEmptyValue: true
          explode: true
          in: query
          name: status
          required: false
          schema:
            type: string
          style: form
        - allowEmptyValue: true
          explode: true
          in: query
          name: applicability
          required: false
          schema:
            type: string
          style: form
        - allowEmptyValue: true
          explode: true
          in: query
          name: outcome
          required: false
          schema:
            type: string
          style: form
        - allowEmptyValue: true
          description: >
            The approval whose answer produced the decisions to return. It is
            the one identifier on this surface that is an id rather than a slug,
            because an approval has none — listing, reading and deciding one all
            take its id, so the id is the handle a caller already holds. It
            matches whether the ask was approved or refused, and can name
            several decisions: an answered batch is split into one decision per
            coherent intent.
          explode: true
          in: query
          name: approval_id
          required: false
          schema:
            type: string
          style: form
        - allowEmptyValue: true
          explode: true
          in: query
          name: limit
          required: false
          schema:
            format: int32
            maximum: 2147483647
            minimum: -2147483648
            type: integer
          style: form
        - allowEmptyValue: true
          explode: true
          in: query
          name: offset
          required: false
          schema:
            format: int32
            maximum: 2147483647
            minimum: -2147483648
            type: integer
          style: form
      responses:
        '200':
          content:
            application/json:
              schema:
                properties:
                  decisions:
                    items:
                      $ref: '#/components/schemas/types.DecisionSummary'
                    type: array
                  limit:
                    description: >
                      the page itself on the org that has decided the most, and
                      no caller has needed one — a short page is the end of the
                      list.
                    format: int32
                    maximum: 2147483647
                    minimum: -2147483648
                    title: >
                      Total is deliberately absent. A count over a filtered scan
                      costs the same as
                    type: integer
                  offset:
                    format: int32
                    maximum: 2147483647
                    minimum: -2147483648
                    type: integer
                type: object
          description: Success response
        default:
          $ref: '#/components/responses/APIError'
components:
  schemas:
    types.DecisionSummary:
      description: >
        continuing agent and a returning operator read.


        It is the same shape for both audiences on purpose. The agent's copy of
        what the organization has committed to cannot be the only one, or a
        human coming back to the workstream has no way to check what it is
        acting on — so the projection carries decision, rationale, authority,
        execution and supersession, and both surfaces render those five facts
        rather than each deriving their own.


        It is deliberately not the whole record: the envelope's declared
        effects, its per-action inputs and its measurement contract are a
        drill-in, and putting them here would push the ledger read past what a
        model can usefully hold.
      properties:
        applicability:
          description: >
            that outlives the work it authorized, or an authorization for
            exactly the actions it named. It travels with the summary because
            the two are read differently — a standing decision is continued
            until something supersedes it, while a one\_shot in the current list
            is work still in flight to see through, not a strategy to keep
            running.
          title: >
            Applicability is standing or one_shot: whether this decision is a
            course
          type: string
        approval_id:
          description: >
            approval producer family. It travels on the row so the join runs in
            both directions from one read: a caller holding an approval filters
            the list by it, and a caller reading a page of decisions can index
            them by the approvals they answer without a call per row.
          format: uuid
          title: >
            ApprovalID is the ask this decision was made on, present only for
            the
          type: string
        authorized_at:
          format: date-time
          type: string
        decided_by_user_id:
          format: uuid
          type: string
        decider_kind:
          description: |
            deterministic\_policy, safe\_default or system.
          title: |
            DeciderKind is who exercised the judgement: human, llm_agent,
          type: string
        decider_rationale:
          description: >
            they supplied any. Usually empty — approving a card records no
            sentence.
          title: >
            DeciderRationale is the deciding human's own words about the answer,
            when
          type: string
        decision_class:
          description: >
            (\`paid\_media.ad\_group.pause\`), provider-agnostic and stable
            across the tools that implement it. Source is the producer family
            that recorded it.
          title: |
            DecisionClass is what KIND of decision this is
          type: string
        evidence_kind:
          description: >
            specified state exists), experimental (a controlled comparison), or
            observational (a before/after movement with no control). Empty when
            the settled effects disagree — a decision with one experimental and
            one deterministic result has no single kind, and picking one would
            attach the stronger claim to both.
          title: |
            EvidenceKind is what KIND of evidence settled it: deterministic (the
          type: string
        execution_status:
          description: >
            change the decision authorized actually reached the outside world.
            pending | started | succeeded | failed | unknown, and empty when the
            decision authorized no action at all.
          title: >
            ExecutionStatus rolls the child actions up into one word: whether
            the
          type: string
        outcome_label:
          description: >
            says the same thing about the same row rather than each deriving its
            own vocabulary from the pair above. Only an experiment may say a
            change "worked"; deterministic evidence says "confirmed" and
            observational says "moved as expected".


            Empty whenever the pair cannot support one phrase — mixed outcomes,
            mixed evidence kinds — because there is no honest single sentence
            for those and the per-effect labels in the detail read are the
            answer.
          title: >
            OutcomeLabel is the server's own words for this outcome, so every
            surface
          type: string
        outcome_status:
          description: >
            not\_met, inconclusive, or \`mixed\` when they disagree. Empty while
            nothing has settled, which is a different fact from inconclusive —
            one says the answer is not in yet, the other says the evidence could
            not produce one.


            Effects that are unmeasurable, censored, or parked in
            measurement\_unavailable contribute nothing here. They are coverage,
            they are visible as such in the detail read and the scorecard, and
            folding them in would let a decision nobody could measure read as
            one that did not work.
          title: >
            OutcomeStatus rolls this decision's SETTLED effects into one word:
            met,
          type: string
        proposed_at:
          format: date-time
          type: string
        slug:
          type: string
        source:
          type: string
        status:
          type: string
        subject_kind:
          description: |
            names it — a campaign, a page, a lead form.
          title: >
            SubjectKind / SubjectLabel name what the decision is about, as the
            operator
          type: string
        subject_label:
          type: string
        superseded_by_decision_slug:
          description: >
            decision that later replaced this one. It carries the same
            past-authorization rule the currentness read applies — a reversal
            somebody PROPOSED and a human then refused has not replaced
            anything, and showing it here would report a course as retired
            exactly when the human voted to keep it.
          title: >
            SupersededByDecisionSlug is the other direction of the same link:
            the
          type: string
        supersedes_decision_slug:
          description: >
            the producer declared the link explicitly — a reversal states what
            it reverses, and nothing infers it from two decisions sharing a
            subject.
          title: >
            SupersedesDecisionSlug names the decision this one replaced. Set
            only when
          type: string
        what:
          description: >
            PRODUCER's rationale — the argument the proposal was made on. When a
            human gave their own reason for the answer it is in
            DeciderRationale, never merged into this one: reading a proposal's
            argument as the approver's reason for accepting it is how a record
            starts attributing motives.
          title: |
            What is the decision in one line of business English; Why is the
          type: string
        why:
          type: string
      title: |
        DecisionSummary is the compact projection of one decision that both a
      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_...).

````