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

# Replace a playbook's steps

> Replaces the playbook's entire step graph with the nodes and connections you provide. This overwrites the existing graph, so send the complete set of steps. Publish the agent for the change to take effect on live conversations.



## OpenAPI

````yaml /openapi.yaml put /agents/{agentId}/playbooks/{id}/graph
openapi: 3.1.0
info:
  title: Flowyte V2 Control-Plane REST API
  version: 1.0.0
  description: >-
    The single REST API for the Flowyte platform (base path `/api/v1`).
    Authenticate every request with a secret API key — `Authorization: Bearer
    flowyte_sk_…` — and each operation lists the scope the key must hold.
    Successful responses use the `ApiResponse<T>` envelope; list responses use
    cursor-based `PaginatedResponse<T>`. Errors are RFC 9457 problem+json.
    Streaming endpoints return Server-Sent Events
    (`event:<type>\ndata:<json>\n\n`, terminating with `event: done`).
  contact:
    name: Flowyte Platform
  license:
    name: Proprietary
servers:
  - url: /api/v1
    description: Flowyte control-plane (versioned URI; additive in v1).
security:
  - apiKey: []
tags:
  - name: Agents
    description: The single user-facing entity.
  - name: Skills
    description: >
      Agent capabilities / tools. A skill is ONE atomic action — typically a
      single API call the agent makes in one step (look up an order, create a
      record, send a message, transfer the call). Use a skill when the task is a
      single step. When a task needs several details gathered across turns
      BEFORE acting, build a Playbook (which gathers the inputs and then calls
      skills) — see the Playbooks tag.
  - name: Integrations
    description: Native OAuth integrations.
  - name: Knowledge
    description: RAG knowledge sources & preview.
  - name: Playbooks
    description: >
      Multi-turn conversation scripts — a node graph (gather → confirm → branch)
      the agent follows to collect several inputs IN ORDER across turns before
      acting. Build a playbook when a single skill call isn't enough because the
      agent must gather MANY details first, or run a SEQUENCE of skills, before
      it can finish (e.g. take a full service request: gather the problem,
      address, and time, confirm, THEN file it; qualify a lead; a multi-step
      intake). A playbook does NOT call an integration itself — it owns the
      conversation and holds the state across turns; the actual action is
      performed by the SKILL(s) it gathers the inputs for. So a playbook
      ORCHESTRATES skills. Rule of thumb — one API call → a Skill; "gather N
      things in order, then submit" → a Playbook that drives the conversation
      and calls the skill(s) at the end.
  - name: Variables
    description: >
      The agent-wide interaction-variable registry (B.4b) — DERIVED at read time
      from the agent's playbooks and skills (collect slots, skill output
      bindings, {var} placeholders) and merged with a thin annotation overlay
      (notes, declared type hints, manual declarations). Read-only observation,
      NEVER a gate: it never validates a reference and never affects authoring,
      publish, or runtime behaviour.
  - name: Guardrails
    description: Deterministic guardrail policies & caller verification.
  - name: Numbers
    description: Phone numbers / DIDs.
  - name: Test
    description: Test, simulate, talk-token, probe.
  - name: Observe
    description: Post-call analytics, conversations, receipts, transcripts.
  - name: Billing
    description: Plans, wallet, usage, fixed phrases.
  - name: Voices
    description: Voice catalog.
  - name: Webhooks
    description: Webhook endpoints & deliveries.
  - name: AuditLogs
    description: API/key activity logs.
  - name: Chat
    description: Chat channel — sessions, messages, OpenAI-compatible, widget.
  - name: PublishableKeys
    description: Browser-safe, one-agent publishable keys.
  - name: Widget
    description: Embed widget config + snippet.
  - name: Uploads
    description: Multipart file uploads backing file_id params
  - name: Meta
    description: Platform metadata (language/SKU/tier capabilities).
paths:
  /agents/{agentId}/playbooks/{id}/graph:
    parameters:
      - $ref: '#/components/parameters/AgentIdPathScoped'
      - name: id
        in: path
        required: true
        schema:
          type: string
    put:
      tags:
        - Playbooks
      summary: Replace a playbook's steps
      description: >-
        Replaces the playbook's entire step graph with the nodes and connections
        you provide. This overwrites the existing graph, so send the complete
        set of steps. Publish the agent for the change to take effect on live
        conversations.
      operationId: putPlaybookGraph
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PlaybookGraphDTO'
      responses:
        '200':
          description: Saved graph.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse_PlaybookGraphDTO'
        '400':
          $ref: '#/components/responses/ValidationError'
        '404':
          $ref: '#/components/responses/NotFound'
      security:
        - apiKey:
            - playbooks:write
components:
  parameters:
    AgentIdPathScoped:
      name: agentId
      in: path
      required: true
      schema:
        type: string
  schemas:
    PlaybookGraphDTO:
      type: object
      required:
        - flowId
        - nodes
        - connections
      properties:
        flowId:
          type: string
        nodes:
          type: array
          items:
            $ref: '#/components/schemas/NodeDTO'
        connections:
          type: array
          items:
            $ref: '#/components/schemas/ConnectionDTO'
    ApiResponse_PlaybookGraphDTO:
      allOf:
        - $ref: '#/components/schemas/ApiResponseBase'
        - type: object
          required:
            - data
          properties:
            data:
              $ref: '#/components/schemas/PlaybookGraphDTO'
    NodeDTO:
      type: object
      description: >-
        One node in a playbook graph — the agent walks the graph INLINE when it
        calls the playbook tool (gather inputs → optionally CALL skills and bind
        their returns → branch → emit text the agent speaks → continue).
        Authored as DATA via PUT .../playbooks/{id}/graph. Node `type` is one
        of: start (the entry, exactly one), collect (ask for + capture one input
        across turns), skill (CALL one of the agent's skills and bind its return
        — the glue), message (emit text the agent speaks; interpolates
        {slot}/{variable}), branch (route on a condition), end. Connect nodes
        with ConnectionDTO edges (default handle `success`; collect and skill
        also emit `needs_input`; branch emits `true`/`false`).
      required:
        - id
        - type
      properties:
        id:
          type: string
          description: Unique node id (use a UUID).
        type:
          type: string
          description: >-
            start | collect | skill | message | branch | end. Aliases accepted:
            action/call-skill/tool/integration→skill, capture→collect,
            prompt/tts-response/say→message, condition/conditional→branch.
        position:
          type: object
          properties:
            x:
              type: number
            'y':
              type: number
        data:
          type: object
          additionalProperties: true
          description: >-
            Per-type config. collect: {slot, prompt, allow_dtmf?, dtmf_length?,
            dtmf_terminator?} — allow_dtmf:true lets the caller SAY or PRESS the
            value on their phone keypad (opt-in, default off); dtmf_length
            auto-submits at that digit count (5=zip, 8=order #, 10=phone), omit
            for a variable-length value the caller ends with dtmf_terminator
            (default "#"). message: {text} (interpolates {slot}/{variable} from
            collected data). start: {message?} optional opening line. SKILL (the
            glue — gather→call→bind→use): {tool, args, output} where `tool` is
            one of THIS agent's skill tool names (e.g. find_client), `args` maps
            each skill parameter to a template filled from the collected
            slots/variables (e.g. {"search":"{caller_name}"}), and `output`
            binds the skill's RETURN into variables by dotted path (e.g.
            {"client_email":"email","client_name":"name"}) so a later
            message/branch can use {client_email}. The skill node calls through
            the SAME gated wall the agent's own skills use — a playbook can only
            call THIS agent's skills, and a confirm-gated write pauses for the
            caller's yes/no then runs on the next turn (no double-fire).
    ConnectionDTO:
      type: object
      description: An edge between two nodes in the playbook graph.
      required:
        - id
        - source
        - target
      properties:
        id:
          type: string
        source:
          type: string
        target:
          type: string
        sourceHandle:
          type: string
        targetHandle:
          type: string
    ApiResponseBase:
      type: object
      required:
        - success
      properties:
        success:
          type: boolean
        message:
          type: string
        errors:
          type: array
          items:
            type: object
            required:
              - field
              - message
            properties:
              field:
                type: string
              message:
                type: string
    ProblemDetails:
      description: RFC 9457 problem+json.
      type: object
      properties:
        type:
          type: string
          format: uri
          default: about:blank
        title:
          type: string
        status:
          type: integer
        detail:
          type: string
        instance:
          type: string
        code:
          type: string
        errors:
          type: array
          items:
            type: object
            properties:
              field:
                type: string
              message:
                type: string
    ApiResponse_Void:
      allOf:
        - $ref: '#/components/schemas/ApiResponseBase'
        - type: object
          properties:
            data:
              type:
                - object
                - 'null'
  responses:
    ValidationError:
      description: Validation failure (errors[] populated on the envelope).
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemDetails'
        application/json:
          schema:
            $ref: '#/components/schemas/ApiResponse_Void'
    NotFound:
      description: Resource not found in org scope.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemDetails'
  securitySchemes:
    apiKey:
      type: oauth2
      description: >
        Flowyte secret API key (`Authorization: Bearer flowyte_sk_live_…`).
        Scope-gated; is scoped to your organization — a key can never reach
        another tenant. The listed scopes in each operation's `apiKey`
        requirement are the scopes that key must hold. The `tokenUrl` is
        nominal: keys are minted in the dashboard.
      flows:
        clientCredentials:
          tokenUrl: /api/v1/api-keys
          scopes:
            agents:read: Read agents.
            agents:write: Create/update/delete agents, publish, rollback.
            knowledge:read: Read knowledge sources & preview.
            knowledge:write: Add/remove knowledge sources, uploads.
            skills:read: Read skills & skill-types.
            skills:write: Create/update/delete skills.
            playbooks:read: Read playbooks & graphs.
            playbooks:write: Create/update/delete playbooks & graphs.
            guardrails:read: Read guardrail policies & caller-verification.
            guardrails:write: Update guardrail policies & caller-verification.
            numbers:read: Read phone numbers / search availability.
            numbers:write: Purchase / assign / release numbers.
            sms:read: Read the org's SMS (10DLC) registration status and numbers.
            sms:write: Save/submit the 10DLC registration and toggle numbers for SMS.
            outbound:read: Read outbound contact lists and campaigns.
            outbound:write: >-
              Create/import contact lists, create/launch/pause/resume/cancel
              outbound campaigns, and enqueue single outbound calls.
            integrations:read: Read connected native integrations (status only — never tokens).
            integrations:write: Discover schemas, set data scoping, and disconnect a connection.
            integrations:connect: >-
              Connect a data source (submit credentials / begin OAuth) — a
              SEPARATE, higher-privilege scope because connecting INGESTS
              credentials and opens a new egress path; a discover/scope/author
              key need not carry it.
            calls:read: Read conversations, receipts, transcripts, analytics.
            analytics:read: >-
              Read the Observe history list, per-agent analytics (the
              answer-rate summary), and the raw knowledge-gap list.
            analytics:write: >-
              Curate knowledge gaps (dismiss / mark in-progress). [M4 —
              reserved]
            billing:read: Read plans, wallet, usage.
            audit:read: Read API/key activity logs.
            webhooks:write: Manage webhook endpoints.
            keys:write: Manage secret API keys.
            chat:read: Read chat sessions & messages.
            chat:write: Create chat sessions & send messages (server-side).
            widgets:read: Read widget config & embed snippet.
            widgets:write: Update widget config.
            pubkeys:read: Read publishable keys.
            pubkeys:write: Manage publishable keys.

````