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

> ## Agent Instructions
> Use the public API base URL: https://api.teamfollowup.ai/api.
> Authenticate public API requests with Authorization: Bearer YOUR_API_KEY.
> Use product-owned terms: agents, campaigns, projects (GoHighLevel sub-accounts), contacts, calls, outcomes, skills, cadences, phone numbers.
> Scope requests by locationId rather than projectName.
> Read the guide linked from each API reference group before recommending an endpoint.

# Update campaign

> Update campaign settings through their owning sections.

Read Get campaign first. Send only the sections you want to change.

| Section | Settings |
| --- | --- |
| trigger | Outbound entry/exclusion tags; reminder appointment calendar; inbound call entry. |
| capabilities | Installed booking, transfer and tagging settings. |
| tools | Installed service-area and tag-check tools. |
| calling | Dialing rules and the campaign’s single cadence, including its ordered steps. |
| outcomes | Wording used to recognize call results. |

Capability/tool maps are partial: omitted entries stay unchanged; null removes one. Arrays replace only their field. Expand a section below for its rules.

Capability and outcome edits through unrelated shared agents return 409; explicit Master agent families share intentionally. A partial save returns 502 with actionResults. Use Idempotency-Key for retries: the same key replays the recorded result, including a partial failure, without repeating completed effects. Read the campaign before sending remaining changes with a new key. Required scope: campaigns:write.

Required API key scope: `campaigns:write`.



## OpenAPI

````yaml /openapi.yaml patch /api/agent-builder/agents/{id}/campaign
openapi: 3.1.0
info:
  title: TFUAI Server API
  version: 1.0.0
  description: >-
    API reference for the TFUAI SaaS server.


    All published endpoints are mounted under `/api`. Responses use a standard
    envelope: `{ "success": true, ... }` on success and `{ "success": false,
    "error": "..." }` on failure.


    Product API modules are being launched module by module. This spec currently
    exposes only contracted public modules.


    Authenticate public API requests with an API key in the `Authorization`
    header: `Authorization: Bearer YOUR_API_KEY`.
servers:
  - url: https://api.teamfollowup.ai
    description: Production API origin. Public API paths are under /api.
security: []
tags:
  - name: Agents
    description: >-
      Build the conversation: identity and settings, script, lead context and
      split testing.
  - name: Analytics
    description: >-
      Understand call volume, pickup, booking and transfer metrics within the
      selected reporting scope.
  - name: Billing
    description: >-
      Balances, spend, purchases and sub-account rebilling. Reference and guides
      only; the builder chatbot has no billing playbook.
  - name: Calls
    description: >-
      Review completed calls, recordings, transcripts and campaign run history;
      distinguish observation from placing a new call.
  - name: Campaigns
    description: >-
      Configure what starts calls, who is eligible, calling windows, caller IDs,
      activation and the actions that follow each outcome.


      What runs after a call lands: for each outcome (booked, opted out, asked
      for a callback…), an ordered chain of actions — tag the contact, move a
      pipeline stage, send an SMS, book an appointment. Stored as a graph:
      `nodes` are the actions, `edges` say what follows what, and
      `dispositionEntries` maps each outcome to the node its chain starts at.


      **Pick the narrowest endpoint that does the job.**


      | To | Call | |

      | --- | --- | --- |

      | See what fires per outcome | `GET .../workflow?view=summary` | Reads as
      plain text, no graph walking |

      | Add steps to an outcome | `POST .../outcomes/{outcome}/nodes` | Server
      derives node ids, edge ids, handles, layout |

      | Change a message, tag or setting | `PATCH .../workflow` | Merges;
      carries no graph, so it cannot damage one |

      | Remove one step | `DELETE .../nodes/{nodeId}` | Also re-links the chain
      around it |

      | Author or replace the whole graph | `PUT .../workflow` | Replaces
      everything you send |


      `PUT` is the only one that can re-wire, position nodes, build an `if`,
      save an unconfigured draft, or copy a whole workflow — and the only one
      that can overwrite a change someone else made after you read it. Use it
      when you are genuinely authoring the graph, and send `expectedVersion`
      when you do. For everything else the narrower endpoints are both easier
      and safer.
  - name: Contacts
    description: >-
      Find contacts and their calls, manage do-not-call status and identify
      internal contacts excluded from reporting.
  - name: In-call Capabilities
    description: >-
      Configure actions and instructions the agent uses during a live call:
      booking, transfers, lookups and custom skills.
  - name: Master agent
    description: >-
      Run a shared agent and campaign across linked projects; manage
      inheritance, local bindings, synchronization and rollout readiness.
  - name: Native Calendar
    description: >-
      The diary of a sub-account with no CRM: its bookable calendars, the free
      slots they offer, and the appointments on them. Availability is computed
      per request against live bookings and is never cached, because a cached
      slot is one somebody else has already taken.
  - name: Native Contacts
    description: >-
      The people a sub-account with no CRM calls, and the fields it keeps on
      them. This is the system of record for those contacts: there is nowhere
      else they exist. A sub-account with a CRM keeps its contacts there and
      every operation here answers 400 for it.
  - name: Phone Numbers
    description: >-
      Find and manage caller IDs, assign numbers to campaigns and understand
      connected Twilio numbers.
  - name: Projects
    description: >-
      Understand project ownership, inspect configuration and validate the local
      resources used by a campaign.
  - name: TFU Live
    description: >-
      Build one TFU Live agent with its Brain, Voice and equipped actions;
      connect it through shared Campaigns.
  - name: Voices
    description: >-
      Browse the voice catalogue and select a voice; configure speech and
      listening behavior in Agents.
paths:
  /api/agent-builder/agents/{id}/campaign:
    patch:
      tags:
        - Campaigns
      summary: Update campaign
      description: >-
        Update campaign settings through their owning sections.


        Read Get campaign first. Send only the sections you want to change.


        | Section | Settings |

        | --- | --- |

        | trigger | Outbound entry/exclusion tags; reminder appointment
        calendar; inbound call entry. |

        | capabilities | Installed booking, transfer and tagging settings. |

        | tools | Installed service-area and tag-check tools. |

        | calling | Dialing rules and the campaign’s single cadence, including
        its ordered steps. |

        | outcomes | Wording used to recognize call results. |


        Capability/tool maps are partial: omitted entries stay unchanged; null
        removes one. Arrays replace only their field. Expand a section below for
        its rules.


        Capability and outcome edits through unrelated shared agents return 409;
        explicit Master agent families share intentionally. A partial save
        returns 502 with actionResults. Use Idempotency-Key for retries: the
        same key replays the recorded result, including a partial failure,
        without repeating completed effects. Read the campaign before sending
        remaining changes with a new key. Required scope: campaigns:write.


        Required API key scope: `campaigns:write`.
      operationId: update-agent-campaign
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            minLength: 1
          description: Agent id.
          example: agent_8a488fcfa8fdbf8ce8ad5ccc45
        - name: locationId
          in: query
          required: false
          schema:
            type: string
            minLength: 1
          description: Pair with campaignId; omit both for primary campaign.
          example: loc_abc123
        - name: campaignId
          in: query
          required: false
          schema:
            type: string
            minLength: 1
          description: Pair with locationId; omit both for primary campaign.
          example: cmp_123
        - name: Idempotency-Key
          in: header
          required: false
          description: >-
            Reuse a unique key for retries of the exact same change. A retry
            returns its saved result or partial-failure receipt without
            repeating effects. Pending or changed-payload reuse returns 409.
            After a partial failure, read the campaign before submitting only
            the remaining changes with a new key.
          schema:
            type: string
            minLength: 1
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CampaignsPatchCampaignRequest'
            examples:
              outcomePrompt:
                value:
                  outcomes:
                    callback:
                      prompt: The person explicitly agreed to another call.
              outboundTrigger:
                value:
                  trigger:
                    type: outbound
                    activeTags:
                      - new_lead
                  calling:
                    s2lDelaySeconds: 30
              bookingCalendar:
                value:
                  capabilities:
                    appointment_booking:
                      calendarId: calendar_123
              transferDestination:
                value:
                  capabilities:
                    live_transfer:
                      transferNumber: '+14155550123'
              reminderImmediate:
                value:
                  calling:
                    speedToLead: true
                    powerDialer: true
                    skipWhenAiBooked: true
                    callbackDoubleDial: false
              confirmationTrigger:
                value:
                  trigger:
                    type: confirmation
                    calendarId: calendar_123
              removeBooking:
                value:
                  capabilities:
                    appointment_booking: null
                  expectedVersion: 3
              cadence:
                value:
                  calling:
                    cadence:
                      steps:
                        - kind: call
                          offsetMinutes: 30
                          doubleDial: true
                        - kind: sms
                          offsetMinutes: 60
                          body: When would be a good time to talk?
              cadenceDays:
                value:
                  calling:
                    cadence:
                      activeDays:
                        - 1
                        - 2
                        - 3
                        - 4
                        - 5
      responses:
        '200':
          description: Campaign facet updated.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CampaignResourceUpdateResponse'
              example:
                success: true
                campaign:
                  id: cmp_123
                  name: Follow up
                  active: false
                  agentId: agent_123
                  campaignType: outbound
                  trigger:
                    type: outbound
                    activeTags:
                      - new_lead
                    inactiveTags: []
                  capabilities: {}
                  tools: {}
                  calling:
                    window: null
                    speedToLead: true
                    powerDialer: false
                  testing:
                    collectContextFields: false
                actionResults:
                  abilities: unchanged
                  settings: saved
                  cadence: unchanged
                  outcomes: unchanged
          headers:
            X-Product-Release:
              description: >-
                Fingerprint of the docs and tool contracts loaded by this
                server. Compare with data-product-release on the API reference
                overview page.
              schema:
                type: string
        '400':
          description: Validation failed or the request body is malformed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AgentsErrorResponse'
              examples:
                default:
                  value:
                    success: false
                    error: VALIDATION
                    message: locationId is required.
                    details:
                      - field: locationId
                        message: locationId is required.
        '401':
          description: Missing or invalid authentication.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AgentsErrorResponse'
              examples:
                default:
                  value:
                    success: false
                    error: Unauthorized
                    message: Authentication required.
        '403':
          description: >-
            Authenticated but missing the required `campaigns:write` scope or
            tenant access.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AgentsErrorResponse'
              examples:
                default:
                  value:
                    success: false
                    error: FORBIDDEN
                    message: No access to agent "agent_8a488fcfa8fdbf8ce8ad5ccc45".
                insufficientScope:
                  value:
                    success: false
                    error: InsufficientScope
                    message: This API key does not have the required scope.
                    requiredScope: campaigns:write
        '404':
          description: Agent or related project not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AgentsErrorResponse'
              examples:
                default:
                  value:
                    success: false
                    error: NOT_FOUND
                    message: Agent "agent_8a488fcfa8fdbf8ce8ad5ccc45" not found.
        '409':
          description: Request conflicts with current agent state.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AgentsErrorResponse'
              examples:
                default:
                  value:
                    success: false
                    error: IN_USE
                    message: Agent is referenced by one or more campaigns or projects.
                    references:
                      projectsV2:
                        - businessName: Acme Roofing
                          campaigns:
                            - id: cmp_123
                              name: Roofing Follow Up
                              agentId: agent_8a488fcfa8fdbf8ce8ad5ccc45
                      masterDb: []
        '429':
          description: Rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AgentsErrorResponse'
              examples:
                default:
                  value:
                    success: false
                    error: TooManyRequests
                    message: Too many requests, please try again later.
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AgentsErrorResponse'
              examples:
                default:
                  value:
                    success: false
                    error: InternalError
                    message: Unexpected server error.
        '502':
          description: >-
            A campaign section save could not be confirmed. Read the action
            results before retrying.
          content:
            application/json:
              example:
                success: false
                error: CAMPAIGN_UPDATE_INCOMPLETE
                message: >-
                  Calling settings were saved; the outcome prompts could not be
                  confirmed.
                actionResults:
                  calling: saved
                  outcomes: unconfirmed
              schema:
                type: object
                required:
                  - success
                  - error
                  - message
                  - actionResults
                properties:
                  success:
                    const: false
                  error:
                    const: CAMPAIGN_UPDATE_INCOMPLETE
                  message:
                    type: string
                  actionResults:
                    type: object
                    additionalProperties:
                      enum:
                        - saved
                        - unchanged
                        - unconfirmed
      security:
        - ApiKeyAuth: []
      x-codeSamples:
        - lang: bash
          label: cURL
          source: |-
            curl --request PATCH \
              --url https://api.teamfollowup.ai/api/agent-builder/agents/{id}/campaign \
              --header 'Authorization: Bearer YOUR_API_KEY' \
              --header 'Content-Type: application/json' \
              --data '{
              "outcomes": {
                "callback": {
                  "prompt": "The person explicitly agreed to another call."
                }
              }
            }'
components:
  schemas:
    CampaignsPatchCampaignRequest:
      type: object
      properties:
        name:
          type: string
          minLength: 1
        description:
          type: string
        active:
          type: boolean
        agentId:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            Change the bound agent separately from capability, tool or outcome
            edits.
        campaignType:
          description: >-
            Optional assertion about the selected campaign; its type cannot be
            changed.
          type: string
          enum:
            - outbound
            - confirmation
            - inbound
        trigger:
          oneOf:
            - type: object
              properties:
                type:
                  type: string
                  const: outbound
                activeTags:
                  type: array
                  items:
                    type: string
                inactiveTags:
                  type: array
                  items:
                    type: string
              required:
                - type
              additionalProperties: false
            - type: object
              properties:
                type:
                  type: string
                  const: confirmation
                calendarId:
                  description: >-
                    Calendar whose booked appointments enter this confirmation
                    campaign. Rescheduling uses this same calendar.
                  type: string
              required:
                - type
              additionalProperties: false
            - type: object
              properties:
                type:
                  type: string
                  const: inbound
              required:
                - type
              additionalProperties: false
          description: >-
            Must match the selected campaign type. Outbound accepts
            activeTags/inactiveTags. Confirmation/reminder accepts calendarId,
            which also supplies rescheduling. Inbound accepts neither tags nor
            an appointment calendar. Include type when changing a trigger; it
            cannot change the campaign type.
        capabilities:
          type: object
          properties:
            appointment_booking:
              anyOf:
                - type: object
                  properties:
                    enabled:
                      type: boolean
                    name:
                      type: string
                      minLength: 1
                    whenToUse:
                      type: string
                    calendarId:
                      type: string
                    calendarRules:
                      type: array
                      items:
                        type: object
                        properties:
                          condition:
                            type: object
                            properties:
                              field:
                                type: string
                                minLength: 1
                                description: >-
                                  The value to test. Resolved at DIAL time, so
                                  it must be known before the call: a contact
                                  field, a location custom value, or a pre-call
                                  variable. A post-call/AI-captured field is
                                  rejected — it is always empty at dial time, so
                                  the rule would never match and every booking
                                  would quietly go to the default calendar.
                              op:
                                type: string
                                enum:
                                  - is_true
                                  - is_false
                                  - is_set
                                  - is_empty
                                  - equals
                                  - not_equals
                                  - contains
                                  - starts_with
                                  - in
                                  - gt
                                  - gte
                                  - lt
                                  - lte
                                description: Same operator set as workflow conditions.
                              value:
                                description: >-
                                  Comparison value; unused by
                                  is_true/is_false/is_set/is_empty.
                            required:
                              - field
                              - op
                            additionalProperties: false
                          calendarId:
                            type: string
                            minLength: 1
                            description: The calendar this rule routes to when it matches.
                        required:
                          - condition
                          - calendarId
                        additionalProperties: false
                    collectAddress:
                      type: boolean
                  additionalProperties: false
                  minProperties: 1
                - type: 'null'
            live_transfer:
              anyOf:
                - type: object
                  properties:
                    enabled:
                      type: boolean
                    name:
                      type: string
                      minLength: 1
                    whenToUse:
                      type: string
                    transferNumber:
                      type: string
                    transferMessage:
                      type: string
                    transferToAssignedUser:
                      type: boolean
                    advancedRouting:
                      type: boolean
                    transferRoutes:
                      type: array
                      items:
                        type: object
                        properties:
                          id:
                            type: string
                            minLength: 1
                          number:
                            type: string
                            minLength: 1
                          condition:
                            type: string
                            minLength: 1
                        required:
                          - id
                          - number
                          - condition
                        additionalProperties: {}
                  additionalProperties: false
                  minProperties: 1
                - type: 'null'
            add_tag:
              anyOf:
                - type: object
                  properties:
                    enabled:
                      type: boolean
                    name:
                      type: string
                      minLength: 1
                    whenToUse:
                      type: string
                    tags:
                      type: array
                      items:
                        type: string
                        minLength: 1
                  additionalProperties: false
                  minProperties: 1
                - type: 'null'
          additionalProperties: false
          minProperties: 1
          description: >-
            Named installed capabilities. Outbound/inbound booking
            calendarId/calendarRules/collectAddress belong inside
            appointment_booking. Confirmation uses trigger.calendarId and has no
            separate booking routing/address settings. Transfer destinations,
            messages and routing belong inside live_transfer. An absent entry
            requires enabled:true to install; null removes it, and omitted
            siblings survive. Zero capabilities is valid. Optionally send
            campaign.metadata.inventoryVersion from Get campaign as
            expectedVersion to reject a stale inventory edit. Agents shared
            outside one explicit Master agent family must be separated before
            editing installations.
        tools:
          type: object
          properties:
            smart_service_area:
              anyOf:
                - type: object
                  properties:
                    enabled:
                      type: boolean
                    name:
                      type: string
                      minLength: 1
                    whenToUse:
                      type: string
                    zips:
                      type: string
                    outOfAreaResponse:
                      type: string
                  additionalProperties: false
                  minProperties: 1
                - type: 'null'
            check_tag:
              anyOf:
                - type: object
                  properties:
                    enabled:
                      type: boolean
                    name:
                      type: string
                      minLength: 1
                    whenToUse:
                      type: string
                    tags:
                      maxItems: 1
                      type: array
                      items:
                        type: string
                        minLength: 1
                    checkingMessage:
                      type: string
                  additionalProperties: false
                  minProperties: 1
                - type: 'null'
          additionalProperties: false
          minProperties: 1
          description: >-
            Partial map of named platform tool installations. An absent entry
            requires enabled:true; null removes only that entry. Omitted tools,
            capabilities and instruction playbooks stay unchanged. Shares the
            inventory expectedVersion guard.
        calling:
          type: object
          properties:
            s2lDoubleDial:
              type: boolean
            s2lDelaySeconds:
              type: integer
              minimum: 0
              maximum: 3600
            s2lDelayMinutes:
              type: integer
              minimum: 0
              maximum: 60
            s2lDelayHaltOnReply:
              type: boolean
            callbackDoubleDial:
              type: boolean
            callNowSkipTags:
              type: array
              items:
                type: string
            callConcurrency:
              anyOf:
                - type: object
                  properties:
                    enabled:
                      type: boolean
                    maxConcurrent:
                      type: integer
                      minimum: 1
                      maximum: 3
                    postTransferDelayMinutes:
                      type: integer
                      minimum: 0
                      maximum: 120
                  additionalProperties: false
                  minProperties: 1
                - type: 'null'
            cadence:
              type: object
              properties:
                name:
                  type: string
                  minLength: 1
                steps:
                  description: >-
                    Complete ordered step list. Omitted preserves the existing
                    schedule. Forward timing edits, including switching between
                    waits and set times, keep queued leads on their step and
                    recalculate their next time from saving. Paused leads stay
                    paused; callbacks and calls underway are unchanged.
                  minItems: 1
                  maxItems: 200
                  type: array
                  items:
                    type: object
                    properties:
                      kind:
                        type: string
                        enum:
                          - call
                          - sms
                          - email
                          - add-tag
                          - move-stage
                          - api-event
                      label:
                        type: string
                        maxLength: 40
                      day:
                        type: integer
                        minimum: 1
                        maximum: 30
                      hour:
                        type: integer
                        minimum: 1
                        maximum: 12
                      minute:
                        type: integer
                        minimum: 0
                        maximum: 59
                      period:
                        type: string
                        enum:
                          - AM
                          - PM
                      offsetMinutes:
                        description: >-
                          Relative wait in minutes after entry for the first
                          step, or after the previous step finishes. Use on
                          every step instead of day/hour/minute/period. When
                          editing queued timing, this wait starts at save time
                          and the step number is preserved.
                        type: integer
                        minimum: 1
                        maximum: 43200
                      minutesBeforeAppt:
                        type: integer
                        minimum: 1
                        maximum: 9007199254740991
                      doubleDial:
                        type: boolean
                      body:
                        type: string
                      snippetId:
                        type: string
                        minLength: 1
                      subject:
                        type: string
                      tags:
                        type: array
                        items:
                          type: string
                          minLength: 1
                      pipelineId:
                        type: string
                        minLength: 1
                      stageId:
                        type: string
                        minLength: 1
                      pipelineName:
                        type: string
                      stageName:
                        type: string
                    required:
                      - kind
                    additionalProperties: false
                activeDays:
                  minItems: 1
                  maxItems: 7
                  type: array
                  items:
                    type: integer
                    minimum: 0
                    maximum: 6
                confirmRemovals:
                  type: boolean
                stepOrder:
                  type: array
                  items:
                    anyOf:
                      - type: integer
                        minimum: 0
                        maximum: 9007199254740991
                      - type: 'null'
                deletions:
                  type: array
                  items:
                    type: object
                    properties:
                      step:
                        type: integer
                        minimum: 0
                        maximum: 9007199254740991
                      leads:
                        type: string
                        enum:
                          - advance
                          - remove
                    required:
                      - step
                      - leads
                    additionalProperties: false
                confirmReorder:
                  type: boolean
              additionalProperties: false
              description: >-
                Configure this campaign’s single schedule. Omitted settings are
                preserved; steps is the complete desired list. Each step has
                exactly one kind and one timing shape. Confirmation campaigns
                require minutesBeforeAppt; outbound steps use waits or fixed
                times. Use confirmRemovals for deliberate step removal.
                Structural reordering uses stepOrder, deletions and
                confirmReorder so in-flight leads can be remapped safely.
            speedToLead:
              description: >-
                Call when the lead enters or an appointment is booked.
                Independent of scheduled follow-up.
              type: boolean
            powerDialer:
              description: Run the scheduled cadence. Independent of the immediate call.
              type: boolean
            skipWhenAiBooked:
              description: >-
                Confirmation campaigns only: skip the immediate call for
                AI-booked appointments; keep scheduled reminders and other skip
                tags.
              type: boolean
            window:
              anyOf:
                - anyOf:
                    - type: object
                      properties:
                        days:
                          minItems: 1
                          type: array
                          items:
                            type: integer
                            minimum: 1
                            maximum: 7
                          description: ISO weekdays the block covers. 1=Mon .. 7=Sun.
                        start:
                          type: string
                          pattern: ^\d{1,2}:\d{2}$
                          description: HH:MM, 24h.
                        end:
                          type: string
                          pattern: ^\d{1,2}:\d{2}$
                          description: HH:MM, 24h.
                        tz:
                          description: >-
                            Ignored on write — the project timezone is used.
                            Returned on reads.
                          type: string
                      required:
                        - days
                        - start
                        - end
                      additionalProperties: {}
                    - minItems: 1
                      type: array
                      items:
                        type: object
                        properties:
                          days:
                            minItems: 1
                            type: array
                            items:
                              type: integer
                              minimum: 1
                              maximum: 7
                            description: ISO weekdays the block covers. 1=Mon .. 7=Sun.
                          start:
                            type: string
                            pattern: ^\d{1,2}:\d{2}$
                            description: HH:MM, 24h.
                          end:
                            type: string
                            pattern: ^\d{1,2}:\d{2}$
                            description: HH:MM, 24h.
                          tz:
                            description: >-
                              Ignored on write — the project timezone is used.
                              Returned on reads.
                            type: string
                        required:
                          - days
                          - start
                          - end
                        additionalProperties: {}
                    - type: object
                      properties:
                        tz:
                          description: Ignored on write — the project timezone is used.
                          type: string
                        windows:
                          minItems: 1
                          type: array
                          items:
                            type: object
                            properties:
                              days:
                                minItems: 1
                                type: array
                                items:
                                  type: integer
                                  minimum: 1
                                  maximum: 7
                                description: ISO weekdays the block covers. 1=Mon .. 7=Sun.
                              start:
                                type: string
                                pattern: ^\d{1,2}:\d{2}$
                                description: HH:MM, 24h.
                              end:
                                type: string
                                pattern: ^\d{1,2}:\d{2}$
                                description: HH:MM, 24h.
                            required:
                              - days
                              - start
                              - end
                            additionalProperties: {}
                          description: >-
                            Every block, in one payload. Replaces the campaign's
                            whole set, never adds to it.
                      required:
                        - windows
                      additionalProperties: {}
                - type: 'null'
            callIfDnd:
              type: boolean
            multipleTimezoneCheck:
              type: boolean
            useWindowTimezone:
              type: boolean
            dropOutsideWindow:
              type: boolean
          additionalProperties: false
          minProperties: 1
          description: >-
            The campaign’s dialing rules and single cadence. Patch cadence.name
            or cadence.activeDays independently; cadence.steps replaces the
            complete step list. No cadenceId is accepted. Outbound and
            confirmation campaigns support independent speedToLead and
            powerDialer switches. For reminders, skipWhenAiBooked suppresses
            only the immediate booking-time call, preserving scheduled
            reminders. Inbound refuses this section.
        fromNumbers:
          type: array
          items:
            type: string
        testing:
          type: object
          properties:
            collectContextFields:
              type: boolean
          additionalProperties: false
          minProperties: 1
        masterCampaignEnabled:
          type: boolean
        outcomes:
          $ref: '#/components/schemas/CampaignOutcomeSettings'
        expectedVersion:
          description: >-
            Optional stale-edit guard. Copy campaign.metadata.inventoryVersion
            from Get campaign. A mismatch returns 409 before capability/tool
            changes. This guards inventory edits, not the whole campaign.
          type: integer
          minimum: 0
          maximum: 9007199254740991
      additionalProperties: false
      minProperties: 1
      description: >-
        Partial update of the selected campaign. Trigger fields must match its
        stored campaignType. Omitted sections and named abilities stay
        unchanged. null removes one named capability/tool; arrays replace only
        that field. An absent ability requires enabled:true to install. Root
        config, calendarId, transferNumber, activeTags and inactiveTags are not
        accepted.
    CampaignResourceUpdateResponse:
      type: object
      additionalProperties: false
      required:
        - success
        - campaign
        - actionResults
      properties:
        success:
          const: true
        campaign:
          $ref: '#/components/schemas/CampaignsCampaign'
        actionResults:
          type: object
          additionalProperties: false
          required:
            - abilities
            - settings
            - cadence
            - outcomes
          properties:
            abilities:
              type: string
              enum:
                - saved
                - unchanged
            settings:
              type: string
              enum:
                - saved
                - unchanged
            cadence:
              type: string
              enum:
                - saved
                - unchanged
            outcomes:
              type: string
              enum:
                - saved
                - unchanged
    AgentsErrorResponse:
      type: object
      additionalProperties: {}
      required:
        - success
        - error
        - message
      properties:
        success:
          type: boolean
        error:
          type: string
          description: Machine-readable error code.
          example: VALIDATION
        message:
          type: string
          description: Human-readable explanation safe to show to an operator.
          example: locationId is required.
        references:
          type: object
          additionalProperties: {}
          description: Structured conflict details. Present on delete conflicts.
        details:
          type: array
          description: Field-level validation details when available.
          items:
            type: object
            additionalProperties: false
            required:
              - field
              - message
            properties:
              field:
                type:
                  - string
                  - 'null'
                example: locationId
              message:
                type: string
                example: locationId is required.
    CampaignOutcomeSettings:
      type: object
      properties:
        opt_out:
          type: object
          properties:
            prompt:
              type: string
              minLength: 1
              maxLength: 10000
          required:
            - prompt
          additionalProperties: false
        callback:
          type: object
          properties:
            prompt:
              type: string
              minLength: 1
              maxLength: 10000
          required:
            - prompt
          additionalProperties: false
        human_needed:
          type: object
          properties:
            prompt:
              type: string
              minLength: 1
              maxLength: 10000
          required:
            - prompt
          additionalProperties: false
        asked_for_info:
          type: object
          properties:
            prompt:
              type: string
              minLength: 1
              maxLength: 10000
          required:
            - prompt
          additionalProperties: false
      additionalProperties: false
      minProperties: 1
      description: >-
        Partial map of outcome prompts. Omitted outcomes are unchanged. Legacy
        storage uses the bound agent; campaign edits return 409 if that agent is
        shared outside one explicit Master agent family. Split variants continue
        sharing their campaign settings.
    CampaignsCampaign:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        description:
          type:
            - string
            - 'null'
        agentId:
          type:
            - string
            - 'null'
        active:
          type: boolean
        locationId:
          type: string
        projectId:
          type: string
        campaignType:
          description: >-
            Optional assertion about the selected campaign; its type cannot be
            changed.
          type: string
          enum:
            - outbound
            - confirmation
            - inbound
        trigger:
          oneOf:
            - type: object
              properties:
                type:
                  type: string
                  const: outbound
                activeTags:
                  type: array
                  items:
                    type: string
                inactiveTags:
                  type: array
                  items:
                    type: string
              required:
                - type
              additionalProperties: false
            - type: object
              properties:
                type:
                  type: string
                  const: confirmation
                calendarId:
                  description: >-
                    Calendar whose booked appointments enter this confirmation
                    campaign. Rescheduling uses this same calendar.
                  type: string
              required:
                - type
              additionalProperties: false
            - type: object
              properties:
                type:
                  type: string
                  const: inbound
              required:
                - type
              additionalProperties: false
          description: >-
            Must match the selected campaign type. Outbound accepts
            activeTags/inactiveTags. Confirmation/reminder accepts calendarId,
            which also supplies rescheduling. Inbound accepts neither tags nor
            an appointment calendar. Include type when changing a trigger; it
            cannot change the campaign type.
        capabilities:
          type: object
          additionalProperties: false
          description: >-
            Installed abilities only, including disabled entries. An empty
            object means none are installed. Never infer an entry from a
            template name.
          properties:
            appointment_booking:
              type: object
              properties:
                enabled:
                  type: boolean
                name:
                  type: string
                  minLength: 1
                whenToUse:
                  type: string
                calendarId:
                  type: string
                calendarRules:
                  type: array
                  items:
                    type: object
                    properties:
                      condition:
                        type: object
                        properties:
                          field:
                            type: string
                            minLength: 1
                            description: >-
                              The value to test. Resolved at DIAL time, so it
                              must be known before the call: a contact field, a
                              location custom value, or a pre-call variable. A
                              post-call/AI-captured field is rejected — it is
                              always empty at dial time, so the rule would never
                              match and every booking would quietly go to the
                              default calendar.
                          op:
                            type: string
                            enum:
                              - is_true
                              - is_false
                              - is_set
                              - is_empty
                              - equals
                              - not_equals
                              - contains
                              - starts_with
                              - in
                              - gt
                              - gte
                              - lt
                              - lte
                            description: Same operator set as workflow conditions.
                          value:
                            description: >-
                              Comparison value; unused by
                              is_true/is_false/is_set/is_empty.
                        required:
                          - field
                          - op
                        additionalProperties: false
                      calendarId:
                        type: string
                        minLength: 1
                        description: The calendar this rule routes to when it matches.
                    required:
                      - condition
                      - calendarId
                    additionalProperties: false
                collectAddress:
                  type: boolean
              additionalProperties: false
            live_transfer:
              type: object
              properties:
                enabled:
                  type: boolean
                name:
                  type: string
                  minLength: 1
                whenToUse:
                  type: string
                transferNumber:
                  type: string
                transferMessage:
                  type: string
                transferToAssignedUser:
                  type: boolean
                advancedRouting:
                  type: boolean
                transferRoutes:
                  type: array
                  items:
                    type: object
                    properties:
                      id:
                        type: string
                        minLength: 1
                      number:
                        type: string
                        minLength: 1
                      condition:
                        type: string
                        minLength: 1
                    required:
                      - id
                      - number
                      - condition
                    additionalProperties: {}
              additionalProperties: false
            add_tag:
              type: object
              properties:
                enabled:
                  type: boolean
                name:
                  type: string
                  minLength: 1
                whenToUse:
                  type: string
                tags:
                  type: array
                  items:
                    type: string
                    minLength: 1
              additionalProperties: false
        tools:
          type: object
          additionalProperties: false
          description: >-
            Installed abilities only, including disabled entries. An empty
            object means none are installed. Never infer an entry from a
            template name.
          properties:
            smart_service_area:
              type: object
              properties:
                enabled:
                  type: boolean
                name:
                  type: string
                  minLength: 1
                whenToUse:
                  type: string
                zips:
                  type: string
                outOfAreaResponse:
                  type: string
              additionalProperties: false
            check_tag:
              type: object
              properties:
                enabled:
                  type: boolean
                name:
                  type: string
                  minLength: 1
                whenToUse:
                  type: string
                tags:
                  maxItems: 1
                  type: array
                  items:
                    type: string
                    minLength: 1
                checkingMessage:
                  type: string
              additionalProperties: false
        calling:
          type: object
          properties:
            s2lDoubleDial:
              type: boolean
            s2lDelaySeconds:
              type: integer
              minimum: 0
              maximum: 3600
            s2lDelayMinutes:
              type: integer
              minimum: 0
              maximum: 60
            s2lDelayHaltOnReply:
              type: boolean
            callbackDoubleDial:
              type: boolean
            callNowSkipTags:
              type: array
              items:
                type: string
            callConcurrency:
              anyOf:
                - type: object
                  properties:
                    enabled:
                      type: boolean
                    maxConcurrent:
                      type: integer
                      minimum: 1
                      maximum: 3
                    postTransferDelayMinutes:
                      type: integer
                      minimum: 0
                      maximum: 120
                  additionalProperties: false
                  minProperties: 1
                - type: 'null'
            cadence:
              anyOf:
                - $ref: '#/components/schemas/CampaignCadence'
                - type: 'null'
              description: >-
                The campaign’s single linked schedule, or null when none is
                configured.
            speedToLead:
              description: >-
                Call when the lead enters or an appointment is booked.
                Independent of scheduled follow-up.
              type: boolean
            powerDialer:
              description: Run the scheduled cadence. Independent of the immediate call.
              type: boolean
            skipWhenAiBooked:
              description: >-
                Confirmation campaigns only: skip the immediate call for
                AI-booked appointments; keep scheduled reminders and other skip
                tags.
              type: boolean
            window:
              anyOf:
                - anyOf:
                    - type: object
                      properties:
                        days:
                          minItems: 1
                          type: array
                          items:
                            type: integer
                            minimum: 1
                            maximum: 7
                          description: ISO weekdays the block covers. 1=Mon .. 7=Sun.
                        start:
                          type: string
                          pattern: ^\d{1,2}:\d{2}$
                          description: HH:MM, 24h.
                        end:
                          type: string
                          pattern: ^\d{1,2}:\d{2}$
                          description: HH:MM, 24h.
                        tz:
                          description: >-
                            Ignored on write — the project timezone is used.
                            Returned on reads.
                          type: string
                      required:
                        - days
                        - start
                        - end
                      additionalProperties: {}
                    - minItems: 1
                      type: array
                      items:
                        type: object
                        properties:
                          days:
                            minItems: 1
                            type: array
                            items:
                              type: integer
                              minimum: 1
                              maximum: 7
                            description: ISO weekdays the block covers. 1=Mon .. 7=Sun.
                          start:
                            type: string
                            pattern: ^\d{1,2}:\d{2}$
                            description: HH:MM, 24h.
                          end:
                            type: string
                            pattern: ^\d{1,2}:\d{2}$
                            description: HH:MM, 24h.
                          tz:
                            description: >-
                              Ignored on write — the project timezone is used.
                              Returned on reads.
                            type: string
                        required:
                          - days
                          - start
                          - end
                        additionalProperties: {}
                    - type: object
                      properties:
                        tz:
                          description: Ignored on write — the project timezone is used.
                          type: string
                        windows:
                          minItems: 1
                          type: array
                          items:
                            type: object
                            properties:
                              days:
                                minItems: 1
                                type: array
                                items:
                                  type: integer
                                  minimum: 1
                                  maximum: 7
                                description: ISO weekdays the block covers. 1=Mon .. 7=Sun.
                              start:
                                type: string
                                pattern: ^\d{1,2}:\d{2}$
                                description: HH:MM, 24h.
                              end:
                                type: string
                                pattern: ^\d{1,2}:\d{2}$
                                description: HH:MM, 24h.
                            required:
                              - days
                              - start
                              - end
                            additionalProperties: {}
                          description: >-
                            Every block, in one payload. Replaces the campaign's
                            whole set, never adds to it.
                      required:
                        - windows
                      additionalProperties: {}
                - type: 'null'
            callIfDnd:
              type: boolean
            multipleTimezoneCheck:
              type: boolean
            useWindowTimezone:
              type: boolean
            dropOutsideWindow:
              type: boolean
          additionalProperties: false
          minProperties: 1
          description: >-
            Calling controls for outbound and confirmation campaigns.
            speedToLead controls immediate calls; powerDialer controls scheduled
            calls. Confirmation campaigns support both. Absent for inbound.
        testing:
          type: object
          properties:
            collectContextFields:
              type: boolean
          additionalProperties: false
          minProperties: 1
        fromNumbers:
          type: array
          items:
            type: string
        masterCampaignEnabled:
          type: boolean
        metadata:
          type: object
          readOnly: true
          additionalProperties: false
          description: >-
            Read-only synchronization information, separate from campaign
            settings. Never send metadata in an update.
          properties:
            inventoryVersion:
              type: integer
              minimum: 0
              readOnly: true
              description: >-
                Revision of the capability/tool inventory only, not of the
                entire campaign. Optional: send this as expectedVersion when
                editing that inventory to reject a stale edit with 409. Omit
                expectedVersion for an ordinary partial update.
            inventoryFreshness:
              type: string
              enum:
                - live
                - cached
              readOnly: true
              description: >-
                live: the capability/tool inventory was checked against the
                current voice configuration. cached: that check failed and the
                last stored configuration was used. This does not describe the
                freshness of other campaign settings.
        createdAt:
          type: string
          format: date-time
          readOnly: true
        updatedAt:
          type: string
          format: date-time
          readOnly: true
        outcomes:
          $ref: '#/components/schemas/CampaignOutcomeValues'
    CampaignCadence:
      type: object
      additionalProperties: false
      required:
        - name
        - steps
        - activeDays
        - editable
      properties:
        name:
          type: string
        steps:
          type: array
          items:
            type: object
            properties:
              kind:
                type: string
                enum:
                  - call
                  - sms
                  - email
                  - add-tag
                  - move-stage
                  - api-event
              label:
                type: string
                maxLength: 40
              day:
                type: integer
                minimum: 1
                maximum: 30
              hour:
                type: integer
                minimum: 1
                maximum: 12
              minute:
                type: integer
                minimum: 0
                maximum: 59
              period:
                type: string
                enum:
                  - AM
                  - PM
              offsetMinutes:
                description: >-
                  Relative wait in minutes after entry for the first step, or
                  after the previous step finishes. Use on every step instead of
                  day/hour/minute/period. When editing queued timing, this wait
                  starts at save time and the step number is preserved.
                type: integer
                minimum: 1
                maximum: 43200
              minutesBeforeAppt:
                type: integer
                minimum: 1
                maximum: 9007199254740991
              doubleDial:
                type: boolean
              body:
                type: string
              snippetId:
                type: string
                minLength: 1
              subject:
                type: string
              tags:
                type: array
                items:
                  type: string
                  minLength: 1
              pipelineId:
                type: string
                minLength: 1
              stageId:
                type: string
                minLength: 1
              pipelineName:
                type: string
              stageName:
                type: string
            required:
              - kind
            additionalProperties: false
        activeDays:
          type: array
          items:
            type: integer
            minimum: 0
            maximum: 6
        editable:
          type: boolean
        editingIssue:
          type: string
          description: >-
            Why this legacy schedule cannot be safely edited through the
            campaign contract.
    CampaignOutcomeValues:
      type: object
      additionalProperties: false
      properties:
        opt_out:
          type: object
          additionalProperties: false
          required:
            - prompt
            - default
            - label
          properties:
            prompt:
              type: string
            default:
              type: string
            label:
              type: string
        callback:
          type: object
          additionalProperties: false
          required:
            - prompt
            - default
            - label
          properties:
            prompt:
              type: string
            default:
              type: string
            label:
              type: string
        human_needed:
          type: object
          additionalProperties: false
          required:
            - prompt
            - default
            - label
          properties:
            prompt:
              type: string
            default:
              type: string
            label:
              type: string
        asked_for_info:
          type: object
          additionalProperties: false
          required:
            - prompt
            - default
            - label
          properties:
            prompt:
              type: string
            default:
              type: string
            label:
              type: string
  securitySchemes:
    ApiKeyAuth:
      type: http
      scheme: bearer
      bearerFormat: API key
      description: 'Send your API key as `Authorization: Bearer YOUR_API_KEY`.'

````