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

# Update an agent

> Updates one or more fields on an agent's draft. To avoid overwriting concurrent edits, send the version you last read in the If-Match header; if it is out of date the request returns 409 with the current version and agent state so you can refetch and retry. Changes apply to the draft only and take effect once you publish the agent.



## OpenAPI

````yaml /openapi.yaml patch /agents/{id}
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/{id}:
    parameters:
      - $ref: '#/components/parameters/AgentIdPath'
    patch:
      tags:
        - Agents
      summary: Update an agent
      description: >-
        Updates one or more fields on an agent's draft. To avoid overwriting
        concurrent edits, send the version you last read in the If-Match header;
        if it is out of date the request returns 409 with the current version
        and agent state so you can refetch and retry. Changes apply to the draft
        only and take effect once you publish the agent.
      operationId: updateAgent
      parameters:
        - $ref: '#/components/parameters/IfMatchHeader'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AgentUpdate'
      responses:
        '200':
          description: Updated agent.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse_Agent'
        '400':
          $ref: '#/components/responses/ValidationError'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          description: >
            Stale `If-Match` (version mismatch). The body includes the current
            agent version + current agent state so the client can rebase and
            retry.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse_Agent'
        '422':
          $ref: '#/components/responses/Unprocessable'
      security:
        - apiKey:
            - agents:write
components:
  parameters:
    AgentIdPath:
      name: id
      in: path
      required: true
      schema:
        type: string
    IfMatchHeader:
      name: If-Match
      in: header
      required: false
      description: >
        Optimistic-concurrency token: the agent `version` the client last read.
        The server increments `agents.version` on every mutation; if `If-Match`
        is stale, the mutation is rejected `409` with the current version +
        current agent state so the client can rebase (refetch + re-apply pending
        field edits + retry).
      schema:
        type: string
  schemas:
    AgentUpdate:
      description: Partial Agent (autosave). Any subset of editable Agent fields.
      allOf:
        - $ref: '#/components/schemas/Agent'
      type: object
    ApiResponse_Agent:
      allOf:
        - $ref: '#/components/schemas/ApiResponseBase'
        - type: object
          required:
            - data
          properties:
            data:
              $ref: '#/components/schemas/Agent'
    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
    Agent:
      type: object
      required:
        - id
        - organizationId
        - name
        - version
        - status
        - persona
        - primaryLanguage
        - languages
        - sku
        - enabledChannels
        - createdAt
        - updatedAt
      properties:
        id:
          type: string
        organizationId:
          type: string
        name:
          type: string
        version:
          type: integer
        status:
          type: string
          enum:
            - draft
            - published
        persona:
          type: string
        goals:
          type: array
          items:
            type: string
        neverDo:
          type: array
          items:
            type: string
        tone:
          type: string
        lexicon:
          $ref: '#/components/schemas/Lexicon'
        primaryLanguage:
          type: string
        languages:
          type: array
          items:
            type: string
        sku:
          $ref: '#/components/schemas/Sku'
        voiceMap:
          type: object
          additionalProperties:
            type: string
        defaultVoiceId:
          type:
            - string
            - 'null'
        voiceSettings:
          $ref: '#/components/schemas/VoiceSettings'
        llmModel:
          type: string
        llmTemperature:
          type: number
        ttsModel:
          type: string
        sttModel:
          type: string
        endpointing:
          $ref: '#/components/schemas/Endpointing'
        greeting:
          type:
            - string
            - 'null'
        handoffConfig:
          $ref: '#/components/schemas/HandoffConfig'
        callControl:
          $ref: '#/components/schemas/CallControl'
        businessHours:
          $ref: '#/components/schemas/BusinessHours'
        enabledChannels:
          type: array
          items:
            $ref: '#/components/schemas/Channel'
        channelOverrides:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/ChannelPolicy'
          description: >-
            Per-channel overrides of the shared agent config, keyed by channel
            ("voice" | "chat"). Only set the keys that should DIFFER from the
            shared config. The common use is a chat-specific opening line, e.g.
            { "chat": { "enabled": true, "greeting": "Hi! How can I help?" } } —
            an empty/omitted chat greeting inherits the agent's main (voice)
            greeting. See ChannelPolicy for the per-channel fields.
        avgTicketCents:
          type:
            - integer
            - 'null'
          description: >
            The customer's saved average ticket / job value in CENTS, used by
            the Observe summary to compute recovered revenue. null = unset (the
            read layer falls back to its conservative default).
        publishedVersionId:
          type:
            - string
            - 'null'
        isActive:
          type: boolean
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
        createdBy:
          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
    ApiResponse_Void:
      allOf:
        - $ref: '#/components/schemas/ApiResponseBase'
        - type: object
          properties:
            data:
              type:
                - object
                - 'null'
    Lexicon:
      type: object
      properties:
        preferred:
          type: array
          items:
            type: string
        banned:
          type: array
          items:
            type: string
        pronunciations:
          type: object
          additionalProperties:
            type: string
    Sku:
      type: string
      enum:
        - code_switch
        - single_language
    VoiceSettings:
      type: object
      properties:
        stability:
          type: number
        similarityBoost:
          type: number
        style:
          type: number
        useSpeakerBoost:
          type: boolean
        speed:
          type: number
    Endpointing:
      type: object
      properties:
        minSilenceMs:
          type: integer
        maxSilenceMs:
          type: integer
        semantic:
          type: boolean
    HandoffConfig:
      type: object
      properties:
        warm:
          type: boolean
        transferDestination:
          type: string
          description: >-
            Default off-net hand-off number (E.164, e.g. +14155551234, or a
            10-digit US number — normalized on save). Used when a transfer is
            needed and no transferRules entry matches.
        escalationThreshold:
          type: number
        contextSummaryUrl:
          type: string
        transferRules:
          type: array
          description: >-
            "Transfer by context" table: each rule routes a described situation
            to a phone number. The agent transfers (blind SIP REFER) to the
            matching destination; a data-lookup skill may instead pass a dynamic
            destination at call time.
          items:
            $ref: '#/components/schemas/TransferRule'
    CallControl:
      type: object
      description: >-
        Per-agent call-control guardrails (max duration, idle/no-response
        handling). All fields optional; an empty object means the runtime
        applies platform defaults (max call 10 min, idle reminders on, end on no
        response).
      properties:
        maxCallSeconds:
          type: integer
          description: >-
            Hard cap on call length in seconds (default 600 = 10 min; ceiling
            3600).
        maxDurationMessage:
          type: string
          description: >-
            Optional line the agent speaks before ending a call that hit the
            max-duration cap.
        idleReminderDelaySeconds:
          type: integer
          description: >-
            Seconds of caller silence before the agent prompts "are you still
            there?" (default 10).
        idleReminderIntervalSeconds:
          type: integer
          description: Seconds between repeated idle prompts after the first (default 10).
        maxIdleReminders:
          type: integer
          description: >-
            How many times to prompt on silence before acting on
            onNoResponseAction (default 2).
        onNoResponseAction:
          type: string
          enum:
            - end_call
            - transfer
          description: >-
            What to do after exhausting idle reminders — end the call (default)
            or transfer to the handoff destination.
        endCallPhrasesEnabled:
          type: boolean
          description: >-
            When true, the agent ends the call after a clear caller goodbye
            (default true).
    BusinessHours:
      type: object
      description: >-
        Per-agent open/closed schedule so the agent knows whether it is
        currently OPEN or CLOSED, speaks the correct local time, and applies the
        configured after-hours behavior. Empty object = unconfigured (no hours
        constraint; the agent behaves as always available). A timezone is
        required whenever a schedule is set — even at 24/7 — so the spoken local
        time is correct.
      properties:
        timezone:
          type: string
          description: >-
            IANA timezone name, e.g. "America/Denver". Required when hours are
            set.
        weekly:
          type: object
          description: >-
            Recurring weekly schedule keyed by lowercase day abbreviation (mon,
            tue, wed, thu, fri, sat, sun). A missing or closed day = closed.
          additionalProperties:
            $ref: '#/components/schemas/DayHours'
        holidays:
          type: array
          description: >-
            One-off date overrides that win over the weekly schedule for their
            dates.
          items:
            $ref: '#/components/schemas/Holiday'
        afterHours:
          $ref: '#/components/schemas/AfterHours'
    Channel:
      type: string
      enum:
        - voice
        - chat
      description: Open enum (future sms|whatsapp|email slot in with no schema change).
    ChannelPolicy:
      type: object
      properties:
        enabled:
          type: boolean
        greeting:
          type:
            - string
            - 'null'
          description: >-
            Channel-specific opening line. Empty/null = inherit the agent's main
            (voice) greeting. Set it on the "chat" channel to give the website
            chat widget its own opener without changing the spoken greeting.
        responseStyle:
          type: string
          enum:
            - spoken
            - markdown
            - plain
        maxSentences:
          type: integer
        verbosity:
          type: string
          enum:
            - concise
            - normal
            - detailed
        quickReplies:
          type: boolean
        typingIndicator:
          type: boolean
      required:
        - enabled
    TransferRule:
      type: object
      description: One row of the transfer-by-context table.
      properties:
        label:
          type: string
          description: Human label for the rule (e.g. "Billing", "Spanish line").
        when:
          type: string
          description: >-
            Plain-language condition the LLM matches against (e.g. "caller asks
            about a refund", "caller is in Texas").
        destination:
          type: string
          description: >-
            Destination phone number (E.164 or 10-digit US — normalized on
            save). Where the call is transferred when this rule applies.
    DayHours:
      type: object
      description: One weekday's open windows.
      properties:
        closed:
          type: boolean
          description: Closed all day (overrides ranges and alwaysOpen).
        alwaysOpen:
          type: boolean
          description: Open all day / 24 hours (overrides ranges).
        ranges:
          type: array
          description: >-
            Ordered open windows. Multiple ranges = a split shift (e.g.
            11:00-14:00 and 17:00-22:00). An end <= start means an overnight
            span into the next day.
          items:
            $ref: '#/components/schemas/TimeRange'
    Holiday:
      type: object
      description: A one-off date (or inclusive date range) overriding the weekly schedule.
      properties:
        name:
          type: string
          description: Spoken/displayed label, e.g. "Christmas Day".
        date:
          type: string
          description: The date (or range start), "YYYY-MM-DD".
        endDate:
          type: string
          description: Optional inclusive range end, "YYYY-MM-DD"; empty = single day.
        closed:
          type: boolean
          description: Closed all day on these dates.
        ranges:
          type: array
          description: Custom open windows on these dates (used only when not closed).
          items:
            $ref: '#/components/schemas/TimeRange'
      required:
        - date
    AfterHours:
      type: object
      description: >-
        The agent's behavior while CLOSED. Capability-based: after hours the
        agent keeps FULL functionality by default — these fields say only what
        changes (whether it can transfer to a live person, and which skills are
        available per window).
      properties:
        mode:
          type: string
          description: >-
            Legacy (superseded by allowHumanTransfer + skillWindows); ignored by
            the runtime.
        message:
          type: string
          description: >-
            Optional closed note the agent may mention while closed; supports
            the {next_open} placeholder.
        allowHumanTransfer:
          type: boolean
          description: >-
            Whether the agent may transfer to a LIVE PERSON after hours (default
            false — most businesses have no one to take the call after hours, so
            the agent helps directly / takes a message instead). All other
            abilities stay available.
        number:
          type: string
          description: >-
            After-hours transfer destination (used when allowHumanTransfer is
            on); empty falls back to the normal handoff destination.
        emergencyNumber:
          type: string
          description: >-
            Optional — route self-declared emergencies to this number even when
            human transfer is otherwise off.
    TimeRange:
      type: object
      description: A single open window in local 24-hour "HH:MM" times.
      properties:
        start:
          type: string
          description: '"HH:MM" 24-hour local open time.'
        end:
          type: string
          description: '"HH:MM" 24-hour local close time (end <= start = overnight).'
      required:
        - start
        - end
  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'
    Unprocessable:
      description: Semantically invalid (e.g. language not in SKU's STT set).
      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.

````