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

# GetLeadPlaybookRevisionAPI mirrors the erdo_get_lead_playbook_revision MCP


> tool: one saved revision in full, which is what explains a decision whose playbook\_revision names it.




## OpenAPI

````yaml /api/openapi.json get /v1/lead-playbook/revisions/{revision}
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, experiments, and bounded outreach.
    Authenticate with a Bearer API key (erdo_api_...) or scoped token
    (erdo_token_...).
  version: '2026-09-22'
servers:
  - url: https://api.erdo.ai
    description: Production
security:
  - bearerAuth: []
paths:
  /v1/lead-playbook/revisions/{revision}:
    get:
      summary: >
        GetLeadPlaybookRevisionAPI mirrors the erdo_get_lead_playbook_revision
        MCP
      description: >
        tool: one saved revision in full, which is what explains a decision
        whose playbook\_revision names it.
      operationId: GET:mcp.GetLeadPlaybookRevisionAPI
      parameters:
        - allowEmptyValue: true
          explode: false
          in: path
          name: revision
          required: true
          schema:
            format: int64
            type: integer
          style: simple
      responses:
        '200':
          content:
            application/json:
              schema:
                properties:
                  agent_id:
                    type: string
                  body:
                    type: string
                  daily_contact_cap:
                    format: int64
                    type: integer
                  enabled:
                    type: boolean
                  read_back:
                    $ref: '#/components/schemas/leadaction.ReadBack'
                  revision:
                    format: int64
                    type: integer
                  saved_at:
                    format: date-time
                    type: string
                  saved_by:
                    type: string
                  signature_name:
                    type: string
                type: object
          description: Success response
        default:
          $ref: '#/components/responses/APIError'
components:
  schemas:
    leadaction.ReadBack:
      description: >
        Only Actions\[].Mode and WorkingHours are enforced; the stages and the
        priority ladder are a picture of the text drawn for the person who wrote
        it, and every evaluation still reads the whole text.
      properties:
        accompanying_email:
          allOf:
            - $ref: '#/components/schemas/leadaction.ReadBackAccompaniment'
          description: >
            person — a text or a call — may also send the lead an email at once.
            Like the cadence it is always filled in, so a read-back stored
            before it existed answers with the default rather than with an empty
            string.
          title: |
            AccompanyingEmail is whether a decision this playbook gates behind a
        actions:
          items:
            $ref: '#/components/schemas/leadaction.ReadBackAction'
          type: array
        cadence:
          allOf:
            - $ref: '#/components/schemas/leadaction.ReadBackCadence'
          description: >
            contact gaps in each reachability state and the new-lead grace.
            Unlike the priority ladder it IS enforced, and normalization always
            fills it in, so a read-back stored before it existed reads back as
            today's behaviour rather than as zeros. See ReadBackCadence in
            reachability.go.
          title: |
            Cadence is how fast this playbook may work one lead: the per-channel
        limits:
          items:
            $ref: '#/components/schemas/leadaction.ReadBackLimit'
          type: array
        priority:
          allOf:
            - $ref: '#/components/schemas/leadaction.ReadBackPriority'
          description: |
            none. Nothing enforces it — see ReadBackPriority.
          title: >
            Priority is the ladder read out of the text, or null when the text
            states
        stages:
          items:
            $ref: '#/components/schemas/leadaction.ReadBackStage'
          type: array
        working_hours:
          $ref: '#/components/schemas/leadaction.WorkingHours'
      title: >
        ReadBack is what Erdo understood from a playbook's text when it was
        saved.
      type: object
    leadaction.ReadBackAccompaniment:
      description: >
        goes out beside a gated text or call.


        Mode is "automatic" (an email may go on its own beside the card) or
        "never". There is deliberately no "approval": an accompanying email that
        itself needed approving would be a second thing in front of a person
        about one lead, which is exactly the shape this engine does not have.
      properties:
        mode:
          type: string
        when:
          description: |
            empty when the text does not say.
          title: >
            When is one short sentence from the text saying when it wants one,
            or
          type: string
      title: >
        ReadBackAccompaniment is what the playbook's text says about the email
        that
      type: object
    leadaction.ReadBackAction:
      description: |
        person. Mode is after platform limits.
      properties:
        kind:
          type: string
        mode:
          type: string
        when:
          type: string
      title: >
        ReadBackAction is one action kind and whether the text lets it run
        without a
      type: object
    leadaction.ReadBackCadence:
      description: >
        the per-channel gaps in each reachability state, and how soon after
        capture the engine may start. It is read out of the text like everything
        else in the read-back, and then clamped to what the platform allows.
      properties:
        confirmed:
          allOf:
            - $ref: '#/components/schemas/leadaction.ContactGaps'
          title: |
            Confirmed applies from the first inbound of any kind onwards.
        new_lead_grace_minutes:
          format: int64
          title: |
            NewLeadGraceMinutes is how long after capture a lead is left alone.
          type: integer
        unconfirmed:
          allOf:
            - $ref: '#/components/schemas/leadaction.ContactGaps'
          title: >
            Unconfirmed applies while the lead has never answered on any
            channel.
      title: >
        ReadBackCadence is how fast the playbook's text says Erdo may work a
        lead:
      type: object
    leadaction.ReadBackLimit:
      description: |
        renderer can say which rules the operator wrote and which Erdo applied.
      properties:
        kind:
          type: string
        mode:
          type: string
        reason:
          type: string
      title: >
        ReadBackLimit is a restriction the platform imposed on top of the text,
        so a
      type: object
    leadaction.ReadBackPriority:
      description: >
        the playbook's own rules put a lead at each level, and the factors the
        playbook forbids taking into account.


        The three levels are fixed — high, medium, low. They are the platform's,
        not the playbook's: the evaluation's response schema constrains the
        model to exactly those three (see evaluationFormat in evaluate.go) and
        the queue's sort, its filters and its badges are built on them. A
        playbook cannot invent a tier; what it decides is which of its rules map
        onto each level.


        NOTHING HERE IS ENFORCED, and this struct is not a guard. The model
        still chooses a decision's priority and writes its priority\_reason, and
        no decision is rejected, downgraded or rewritten because its priority
        disagrees with this ladder. The read-back exists so an operator can SEE
        what Erdo understood — until now the ladder reached the model only as
        raw playbook text, so a misread rule was invisible until decisions came
        out wrong. Whether to enforce it is a product decision nobody has taken.
      properties:
        forbidden_factors:
          description: >
            a lead's country, city, name or language, say. Empty when it forbids
            none.
          items:
            type: string
          title: >
            ForbiddenFactors are the things the text says must NOT affect
            priority —
          type: array
        high:
          description: >
            one short phrase each, in the text's own terms ("budget $2M or
            more", "they replied to us", "timeline beyond a year").
          items:
            type: string
          title: >
            High, Medium and Low are the conditions the text gives for each
            level,
          type: array
        low:
          items:
            type: string
          type: array
        medium:
          items:
            type: string
          type: array
      title: >
        ReadBackPriority is the priority ladder Erdo read out of a playbook:
        which of
      type: object
    leadaction.ReadBackStage:
      description: |
        from that stage.
      properties:
        actions:
          items:
            type: string
          type: array
        name:
          type: string
        summary:
          type: string
      title: >
        ReadBackStage is one stage the text describes, with the actions it
        allows
      type: object
    leadaction.WorkingHours:
      description: |
        lowercase three-letter names; Start and End are "HH:MM" in Timezone.
      properties:
        days:
          items:
            type: string
          type: array
        end:
          type: string
        start:
          type: string
        timezone:
          type: string
      title: |
        WorkingHours is the window automatic contact is allowed in. Days are
      type: object
    leadaction.ContactGaps:
      description: >
        channel. Zero means "the text did not say", which reads as the default,
        never as "no gap at all".


        BetweenChannels is how long after a contact on one channel the next
        contact on a DIFFERENT channel waits ("text them two minutes after the
        call"). Empty when the playbook sets no such wait.
      properties:
        between_channels:
          items:
            $ref: '#/components/schemas/leadaction.ChannelStep'
          type: array
        call_minutes:
          format: int64
          type: integer
        email_minutes:
          format: int64
          type: integer
        sms_minutes:
          format: int64
          type: integer
      title: |
        ContactGaps is the least time between two contacts to one lead on ONE
      type: object
    leadaction.ChannelStep:
      description: |
        contact on After, a contact on Next waits Minutes.
      properties:
        after:
          type: string
        minutes:
          format: int64
          type: integer
        next:
          type: string
      title: |
        ChannelStep is one wait the playbook sets between two channels: after 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_...).

````