> ## 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, calls, campaigns, contacts, phone numbers, billing, and configuration.

# Create agent

> Create a voice agent for one project from a campaign type and one or more starting capabilities. The type decides what triggers the call; the capabilities decide what the agent can do on it, and each one installs its tool, post-call fields, workflow route, and required configuration together. Optional `config` fields are applied during creation so API clients can provision a ready-to-use agent in one request. The operation provisions the agent, campaign, and workflow together, then rolls back known partial failures.

Required API key scope: `agents:write`.



## OpenAPI

````yaml /openapi.yaml post /api/agent-builder/agents
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.
  - url: https://devapi.teamfollowup.ai
    description: Development API origin. Public API paths are under /api.
security: []
tags:
  - name: Agents
    description: Manage voice agents, campaigns, workflows, and outcomes.
  - name: Analytics
    description: >-
      Minimal, non-billing performance summary: volume, conversion, and pickup
      metrics.
  - name: Calls
    description: Review calls, test runs, and execution history.
  - name: Campaign Workflows
    description: >-
      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/digest` | 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: Contact list, filters, contact call history, and do-not-call actions.
  - name: GHL
    description: CRM variables and contact helpers used by agent and campaign setup flows.
  - name: Phone Numbers
    description: >-
      Caller ID pool, number search, assignment, movement, and release
      endpoints.
  - name: Power Dialer
    description: >-
      Power Dialer queue, lead cadence, callback, parked lead, and campaign
      schedule endpoints.
  - name: Projects
    description: >-
      Project management endpoints: list, update, disconnect, configure project
      campaigns, and validate setup.
  - name: Skills and Tools
    description: Manage reusable agent behaviors and in-call tool descriptions.
  - name: Voices
    description: Voice catalogue endpoints for choosing the voice used by an agent.
paths:
  /api/agent-builder/agents:
    post:
      tags:
        - Agents
      summary: Create agent
      description: >-
        Create a voice agent for one project from a campaign type and one or
        more starting capabilities. The type decides what triggers the call; the
        capabilities decide what the agent can do on it, and each one installs
        its tool, post-call fields, workflow route, and required configuration
        together. Optional `config` fields are applied during creation so API
        clients can provision a ready-to-use agent in one request. The operation
        provisions the agent, campaign, and workflow together, then rolls back
        known partial failures.


        Required API key scope: `agents:write`.
      operationId: post-agent-builder-agents
      parameters:
        - name: Idempotency-Key
          in: header
          required: false
          schema:
            type: string
            minLength: 1
            maxLength: 255
          description: >-
            Optional retry key for create-style operations. Reusing the same key
            with the same request returns the original result; reusing it with a
            different request returns 409.
          example: agent-create-20260709-001
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AgentsCreateAgentRequest'
            examples:
              default:
                value:
                  locationId: loc_abc123
                  name: Roofing Follow Up
                  agentType: outreach
                  capabilityIds:
                    - live_transfer
                    - add_tag
                  campaign:
                    activeTags:
                      - new_lead
                    inactiveTags:
                      - do_not_call
                    dialing: s2l_pd
                    callingWindow:
                      days:
                        - 1
                        - 2
                        - 3
                        - 4
                        - 5
                      start: '09:00'
                      end: '17:00'
                      tz: America/New_York
                    config:
                      calendarId: calendar_primary
                      s2lDoubleDial: true
                  config:
                    llm:
                      generalPrompt: |-
                        # Context
                        Qualify the lead and book an appointment.
                      beginMessage: Hi, this is Sarah from Acme Roofing.
                    voice:
                      voiceId: custom_voice_d7515c44b4aaea0ceade0a37ae
                      temperature: 0.8
                      speed: 1
                    language:
                      language:
                        - en-US
                      denoisingMode: noise-cancellation
                    analysis:
                      outcomes:
                        opt_out: The lead explicitly asked not to be contacted again.
                        callback: The lead asked to be called back at a later time.
                      fields:
                        - key: customer_name
                          type: text
                          prompt: The full name of the lead.
                          required: true
      responses:
        '200':
          description: Original successful response for a replayed Idempotency-Key request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AgentsAgentResponse'
              examples:
                default:
                  value:
                    success: true
                    idempotentReplay: true
                    agent:
                      id: agent_1ffdb9717444d0e77346838911
                      agentId: agent_1ffdb9717444d0e77346838911
                      agentType: outreach
                      name: Roofing Follow Up
                      isActive: true
                      hasCustomPrompt: true
                      platformFieldNames:
                        - call_summary
                        - callback
                      campaign:
                        id: cmp_123
                        name: Roofing Follow Up
                        system: appointment_booking
                        agentType: appointment_booking
                        dialing: s2l_pd
                        active: false
                        isActive: false
                        type: s2l_pd
                        activeTags:
                          - new_lead
                        inactiveTags:
                          - do_not_call
                        callingWindow: null
                        config:
                          cadenceId: cad_123
                          calendarId: calendar_primary
                        fromNumbers:
                          - '+14155551234'
                        projectId: proj_123
                        locationId: loc_abc123
                        businessName: Acme Roofing
                        createdAt: '2026-07-08T10:00:00.000Z'
                        updatedAt: '2026-07-08T10:00:00.000Z'
                      config:
                        agent:
                          agentName: Roofing Follow Up
                        llm:
                          beginMessage: Hi, this is Sarah from Acme Roofing.
                          generalPrompt: |-
                            # Context
                            Qualify the lead and book an appointment.
                        voice:
                          voiceId: custom_voice_d7515c44b4aaea0ceade0a37ae
                          ambientSound: null
                          ambientSoundVolume: 0.75
                          temperature: 0.8
                          speed: 1
                        interaction:
                          enableBackchannel: true
                          backchannelFrequency: 0.6
                          backchannelWords:
                            - yeah
                            - got it
                        language:
                          language: en-US
                          denoisingMode: noise-cancellation
                        analysis:
                          outcomes:
                            opt_out: >-
                              The lead explicitly asked not to be contacted
                              again.
                            callback: The lead asked to be called back at a later time.
                            human_needed: A human team member needs to review or follow up.
                            asked_for_info: The lead asked to receive additional information.
                          fields:
                            - key: customer_name
                              type: text
                              prompt: The full name of the lead.
                              required: true
                          locked:
                            - call_summary
                            - call_successful
                      createdAt: '2026-07-08T10:00:00.000Z'
                      updatedAt: '2026-07-08T10:00:00.000Z'
        '201':
          description: Agent created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AgentsAgentResponse'
              examples:
                default:
                  value:
                    success: true
                    agent:
                      id: agent_1ffdb9717444d0e77346838911
                      agentId: agent_1ffdb9717444d0e77346838911
                      agentType: outreach
                      name: Roofing Follow Up
                      isActive: true
                      hasCustomPrompt: true
                      platformFieldNames:
                        - call_summary
                        - callback
                      campaign:
                        id: cmp_123
                        name: Roofing Follow Up
                        system: appointment_booking
                        agentType: appointment_booking
                        dialing: s2l_pd
                        active: false
                        isActive: false
                        type: s2l_pd
                        activeTags:
                          - new_lead
                        inactiveTags:
                          - do_not_call
                        callingWindow: null
                        config:
                          cadenceId: cad_123
                          calendarId: calendar_primary
                        fromNumbers:
                          - '+14155551234'
                        projectId: proj_123
                        locationId: loc_abc123
                        businessName: Acme Roofing
                        createdAt: '2026-07-08T10:00:00.000Z'
                        updatedAt: '2026-07-08T10:00:00.000Z'
                      config:
                        agent:
                          agentName: Roofing Follow Up
                        llm:
                          beginMessage: Hi, this is Sarah from Acme Roofing.
                          generalPrompt: |-
                            # Context
                            Qualify the lead and book an appointment.
                        voice:
                          voiceId: custom_voice_d7515c44b4aaea0ceade0a37ae
                          ambientSound: null
                          ambientSoundVolume: 0.75
                          temperature: 0.8
                          speed: 1
                        interaction:
                          enableBackchannel: true
                          backchannelFrequency: 0.6
                          backchannelWords:
                            - yeah
                            - got it
                        language:
                          language: en-US
                          denoisingMode: noise-cancellation
                        analysis:
                          outcomes:
                            opt_out: >-
                              The lead explicitly asked not to be contacted
                              again.
                            callback: The lead asked to be called back at a later time.
                            human_needed: A human team member needs to review or follow up.
                            asked_for_info: The lead asked to receive additional information.
                          fields:
                            - key: customer_name
                              type: text
                              prompt: The full name of the lead.
                              required: true
                          locked:
                            - call_summary
                            - call_successful
                      createdAt: '2026-07-08T10:00:00.000Z'
                      updatedAt: '2026-07-08T10:00:00.000Z'
        '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.
        '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 `agents: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_1ffdb9717444d0e77346838911".
                insufficientScope:
                  value:
                    success: false
                    error: InsufficientScope
                    message: This API key does not have the required scope.
                    requiredScope: agents: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_1ffdb9717444d0e77346838911" not found.
        '409':
          description: Request conflicts with current agent state.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AgentsErrorResponse'
              examples:
                default:
                  value:
                    success: false
                    error: CONFLICT
                    message: >-
                      Another active campaign already triggers on the same
                      active-tag set. Two campaigns with identical active tags
                      would both fire on the same webhook.
        '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.
      security:
        - ApiKeyAuth: []
      x-codeSamples:
        - lang: bash
          label: cURL
          source: |-
            curl --request POST \
              --url https://api.teamfollowup.ai/api/agent-builder/agents \
              --header 'Authorization: Bearer YOUR_API_KEY' \
              --header 'Content-Type: application/json' \
              --data '{
              "locationId": "loc_abc123",
              "name": "Roofing Follow Up",
              "agentType": "outreach",
              "capabilityIds": [
                "live_transfer",
                "add_tag"
              ],
              "campaign": {
                "activeTags": [
                  "new_lead"
                ],
                "inactiveTags": [
                  "do_not_call"
                ],
                "dialing": "s2l_pd",
                "callingWindow": {
                  "days": [
                    1,
                    2,
                    3,
                    4,
                    5
                  ],
                  "start": "09:00",
                  "end": "17:00",
                  "tz": "America/New_York"
                },
                "config": {
                  "calendarId": "calendar_primary",
                  "s2lDoubleDial": true
                }
              },
              "config": {
                "llm": {
                  "generalPrompt": "# Context\nQualify the lead and book an appointment.",
                  "beginMessage": "Hi, this is Sarah from Acme Roofing."
                },
                "voice": {
                  "voiceId": "custom_voice_d7515c44b4aaea0ceade0a37ae",
                  "temperature": 0.8,
                  "speed": 1
                },
                "language": {
                  "language": [
                    "en-US"
                  ],
                  "denoisingMode": "noise-cancellation"
                },
                "analysis": {
                  "outcomes": {
                    "opt_out": "The lead explicitly asked not to be contacted again.",
                    "callback": "The lead asked to be called back at a later time."
                  },
                  "fields": [
                    {
                      "key": "customer_name",
                      "type": "text",
                      "prompt": "The full name of the lead.",
                      "required": true
                    }
                  ]
                }
              }
            }'
components:
  schemas:
    AgentsCreateAgentRequest:
      type: object
      additionalProperties: {}
      required:
        - locationId
        - name
        - agentType
      allOf:
        - if:
            properties:
              agentType:
                enum:
                  - outreach
                  - inbound
            required:
              - agentType
          then:
            required:
              - capabilityIds
      properties:
        locationId:
          type: string
          minLength: 1
          description: >-
            Must be a connected V2 project (a GHL location connected to TFU).
            Passing an unconnected location id returns 404 "V2 project for
            locationId=… not found".
          example: loc_abc123
        name:
          type: string
          minLength: 1
          example: Roofing Follow Up
        agentType:
          type: string
          enum:
            - outreach
            - inbound
            - appointment
          description: >-
            Campaign type returned by List agent types, which decides what
            triggers the call: `outreach` on a CRM tag, `inbound` on an incoming
            call, `appointment` when an appointment is booked. An unrecognised
            value is rejected with a 400 listing the valid types. Integrations
            written before this taxonomy may instead send a legacy V2 template
            id as `system`, with no `agentType`; that path still works and
            infers the type and capabilities from the template, but it is not
            the supported way to create an agent.
          example: outreach
        capabilityIds:
          type: array
          minItems: 1
          items:
            type: string
            enum:
              - appointment_booking
              - live_transfer
              - add_tag
          description: >-
            Behaviours to install on the new agent. **Required for `outreach`
            and `inbound`** — omitting it returns a 400 reading "At least one
            capability is required". Silently ignored for `appointment`, which
            always starts with Appointment Booking. Every id is installed with
            its tool, post-call fields, workflow route, and config gate. The
            FIRST id additionally selects the base template the agent is cloned
            from, which is what the campaign reports as `system`; the others are
            installed on top of it.
          example:
            - live_transfer
            - add_tag
        templateId:
          type: string
          enum:
            - appointment_booking
            - live_transfer
            - add_tag
          description: >-
            Single-capability form of `capabilityIds`, kept for callers written
            before multi-select. Ignored when `capabilityIds` is present.
          example: live_transfer
        campaign:
          $ref: '#/components/schemas/AgentsCreateCampaignRequest'
        config:
          $ref: '#/components/schemas/AgentsMutableConfig'
    AgentsAgentResponse:
      type: object
      additionalProperties: false
      required:
        - success
        - agent
      properties:
        success:
          type: boolean
        idempotentReplay:
          type: boolean
          description: >-
            True when returned from a previous successful Idempotency-Key
            request.
        agent:
          $ref: '#/components/schemas/AgentsAgent'
    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.
    AgentsCreateCampaignRequest:
      type: object
      additionalProperties: {}
      description: >-
        Optional campaign fields applied during Create agent. Server-owned
        fields such as id, agentId, name, agentType, active, createdAt, and
        updatedAt are ignored — the agent starts paused and inherits its agent
        type from the parent request.
      properties:
        description:
          type: string
          example: Call new leads as soon as they enter the intake flow.
        activeTags:
          type: array
          items:
            type: string
          example:
            - new_lead
        inactiveTags:
          type: array
          items:
            type: string
          example:
            - do_not_call
        callIfDnd:
          type: boolean
          example: false
        dialing:
          type: string
          enum:
            - s2l
            - pd
            - s2l_pd
          description: >-
            Dispatch mode: speed-to-lead, power-dialer, or both. Omit to let the
            server derive the default for the agent type; outbound agent types
            default to `pd`. Prefer omitting over sending `null`: a campaign
            with no dispatch mode is inert, so send a concrete mode or leave the
            field out.
          example: s2l_pd
        callingWindow:
          oneOf:
            - $ref: '#/components/schemas/CampaignsCallingWindow'
            - type: array
              items:
                $ref: '#/components/schemas/CampaignsCallingWindow'
            - type: 'null'
        multipleTimezoneCheck:
          type: boolean
          example: true
        dropOutsideWindow:
          type: boolean
          example: false
        config:
          $ref: '#/components/schemas/CampaignsConfig'
        fromNumbers:
          type: array
          items:
            type: string
          example:
            - '+14155551234'
        masterCampaignEnabled:
          type: boolean
          example: false
    AgentsMutableConfig:
      type: object
      additionalProperties: false
      description: >-
        Optional editable agent configuration accepted on create and update.
        Omitted fields keep their template defaults on create, or remain
        unchanged on update.
      properties:
        llm:
          $ref: '#/components/schemas/AgentsMutablePromptConfig'
        voice:
          $ref: '#/components/schemas/AgentsMutableVoiceConfig'
        interaction:
          $ref: '#/components/schemas/AgentsMutableInteractionConfig'
        language:
          $ref: '#/components/schemas/AgentsMutableLanguageConfig'
        analysis:
          $ref: '#/components/schemas/AgentsAnalysisWrite'
        callScreening:
          $ref: '#/components/schemas/AgentsMutableCallScreeningConfig'
    AgentsAgent:
      type: object
      additionalProperties: {}
      required:
        - id
        - agentType
        - name
      properties:
        id:
          type: string
          example: agent_1ffdb9717444d0e77346838911
        agentId:
          type: string
          description: >-
            Same value as `id`, emitted for callers that key on the agent id
            explicitly.
          example: agent_1ffdb9717444d0e77346838911
        agentType:
          type:
            - string
            - 'null'
          enum:
            - outreach
            - inbound
            - appointment
            - null
          description: >-
            Campaign type this agent was created as. Null when no recognised
            type can be resolved from the agent or its campaign.
          example: outreach
        name:
          type: string
          example: Roofing Follow Up
        isActive:
          type: boolean
          description: >-
            The agent's live state, driven by its campaign switch. Note the
            spelling: this endpoint returns `isActive`, while List agents
            returns the same state as `active`. Read both if you consume the two
            endpoints together.
          example: true
        hasCustomPrompt:
          type: boolean
          description: >-
            Whether the agent has been given a prompt of its own, rather than
            still carrying the one it was created with.
          example: true
        platformFieldNames:
          type: array
          items:
            type: string
          description: >-
            Post-call fields the platform manages on this agent. They are always
            kept, and a post-call update that omits them does not remove them.
          example:
            - call_summary
            - callback
        config:
          $ref: '#/components/schemas/AgentsConfig'
        campaign:
          $ref: '#/components/schemas/CampaignsCampaign'
        partialFailures:
          type: array
          items:
            type: string
          description: Non-blocking downstream sync failures from a successful update.
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
    CampaignsCallingWindow:
      type: object
      additionalProperties: false
      required:
        - days
        - start
        - end
        - tz
      properties:
        days:
          type: array
          minItems: 1
          items:
            type: integer
            minimum: 1
            maximum: 7
          description: ISO weekday numbers. Monday is 1 and Sunday is 7.
          example:
            - 1
            - 2
            - 3
            - 4
            - 5
        start:
          type: string
          pattern: ^\d{2}:\d{2}$
          example: '09:00'
        end:
          type: string
          pattern: ^\d{2}:\d{2}$
          example: '17:00'
        tz:
          type: string
          example: America/New_York
    CampaignsConfig:
      type: object
      additionalProperties: {}
      properties:
        cadenceId:
          type: string
          example: cadence_123
        calendarId:
          type: string
          example: calendar_primary
        collectAddress:
          type: boolean
          example: true
        transferNumber:
          type: string
          example: '+14155550100'
        transferToAssignedUser:
          type: boolean
          example: false
        advancedRouting:
          type: boolean
          example: false
        transferRoutes:
          type: array
          items:
            $ref: '#/components/schemas/CampaignsTransferRoute'
        s2lDoubleDial:
          type: boolean
          example: true
        callbackDoubleDial:
          type: boolean
          example: true
        callNowSkipTags:
          type: array
          items:
            type: string
          example:
            - already_booked
        appliedTag:
          type: string
          description: >-
            Objective tag for `add_tag` agents: the GHL tag applied when the
            tagging objective is met.
          example: qualified_lead
        confirmedTag:
          type: string
          description: >-
            Objective tag for `appointment_confirmation` agents: the GHL tag
            applied when the appointment is confirmed.
          example: appt_confirmed
        fallbackTag:
          type: string
          description: >-
            Objective tag for `live_transfer_and_tag` agents: the GHL tag
            applied when the live transfer fails to connect, so the lead still
            gets follow-up.
          example: transfer_failed
    AgentsMutablePromptConfig:
      type: object
      additionalProperties: false
      properties:
        generalPrompt:
          type: string
          description: Operator-visible prompt context.
          example: |-
            # Context
            Qualify the lead and book an appointment.
        beginMessage:
          type: string
          description: First message the agent says when the call starts.
          example: Hi, this is Sarah from Acme Roofing.
    AgentsMutableVoiceConfig:
      type: object
      additionalProperties: false
      properties:
        voiceId:
          type: string
          description: Voice id selected from the voice catalogue.
          example: custom_voice_d7515c44b4aaea0ceade0a37ae
        ambientSound:
          type:
            - string
            - 'null'
          enum:
            - coffee-shop
            - convention-hall
            - summer-outdoor
            - mountain-outdoor
            - static-noise
            - call-center
            - null
          description: Set to null to remove background ambience.
          example: null
        ambientSoundVolume:
          type: number
          minimum: 0
          maximum: 2
          description: >-
            How loud the ambient sound sits under the voice. 1 is the standard
            level, 0 mutes it. Only audible when ambientSound is set.
          example: 0.75
        temperature:
          type: number
          minimum: 0
          maximum: 2
          description: Voice expressiveness.
          example: 0.8
        speed:
          type: number
          minimum: 0.5
          maximum: 2
          description: Voice speaking pace. 1 is normal speed.
          example: 1
    AgentsMutableInteractionConfig:
      type: object
      additionalProperties: false
      properties:
        enableBackchannel:
          type: boolean
          description: >-
            Whether the agent may use short acknowledgement words while
            listening.
          example: true
        backchannelFrequency:
          type: number
          minimum: 0
          maximum: 1
          description: Backchannel frequency from 0 to 1.
          example: 0.6
        backchannelWords:
          type: array
          items:
            type: string
          example:
            - yeah
            - got it
        responsiveness:
          type: number
          minimum: 0
          maximum: 1
          description: >-
            How soon the agent starts talking after the caller stops. Lower
            waits longer, higher replies sooner.
          example: 0.92
        fillerWords:
          $ref: '#/components/schemas/AgentsFillerWords'
    AgentsMutableLanguageConfig:
      type: object
      additionalProperties: false
      properties:
        language:
          oneOf:
            - type: string
              example: en-US
            - type: array
              items:
                type: string
              example:
                - en-US
                - es-ES
          description: >-
            Speech recognition locale or ordered locales for multilingual
            agents.
        denoisingMode:
          type: string
          enum:
            - no-denoise
            - noise-cancellation
            - noise-and-background-speech-cancellation
          example: noise-cancellation
    AgentsAnalysisWrite:
      type: object
      additionalProperties: false
      description: >-
        Post-call analysis to set. Send the editable outcomes and your custom
        fields. Platform-managed fields are always retained, so a partial
        payload cannot remove them.
      properties:
        outcomes:
          $ref: '#/components/schemas/AgentsOutcomes'
        fields:
          type: array
          items:
            $ref: '#/components/schemas/AgentsCustomField'
    AgentsMutableCallScreeningConfig:
      type: object
      additionalProperties: false
      properties:
        callPurpose:
          type: string
          maxLength: 300
          description: >-
            The sentence the agent speaks verbatim when iOS or Android call
            screening answers and asks why it is calling. A literal utterance,
            not an instruction.
          example: I'm calling to confirm your upcoming appointment with Acme Roofing.
    AgentsConfig:
      type: object
      additionalProperties: {}
      description: >-
        Editable agent configuration, grouped by concern. Unknown future keys
        may be present.
      properties:
        agent:
          $ref: '#/components/schemas/AgentsConfigAgent'
        llm:
          $ref: '#/components/schemas/AgentsConfigPrompt'
        voice:
          $ref: '#/components/schemas/AgentsConfigVoice'
        interaction:
          $ref: '#/components/schemas/AgentsConfigInteraction'
        language:
          $ref: '#/components/schemas/AgentsConfigLanguage'
        analysis:
          $ref: '#/components/schemas/AgentsAnalysis'
    CampaignsCampaign:
      type: object
      additionalProperties: {}
      required:
        - id
        - name
        - createdAt
        - updatedAt
      properties:
        id:
          type: string
          example: campaign_speed_to_lead_123
        name:
          type: string
          example: Speed to Lead
        active:
          type: boolean
          description: The campaign's live state.
          example: false
        masterCampaignEnabled:
          type: boolean
          example: false
        description:
          type:
            - string
            - 'null'
          example: Call new leads as soon as they enter the intake flow.
        activeTags:
          type: array
          items:
            type: string
          example:
            - new_lead
        inactiveTags:
          type: array
          items:
            type: string
          example:
            - do_not_call
        callIfDnd:
          type: boolean
          example: false
        agentId:
          type:
            - string
            - 'null'
          example: agent_2b7c9f4a
        agentName:
          type:
            - string
            - 'null'
          example: Front Desk Agent
        system:
          type:
            - string
            - 'null'
          description: >-
            Legacy V2 template this campaign was cloned from. It is the clone
            SOURCE, not the campaign's behaviour: what the agent can do is
            decided by its installed capabilities, and on agents created since
            multi-capability support this value only reflects the FIRST
            capability selected. Read it as provenance. Normally one of
            `appointment_confirmation`, `appointment_booking`, `live_transfer`,
            `live_transfer_and_tag`, `live_transfer_and_booking`, `add_tag`,
            `inbound_receptionist`, but this field is returned as stored and is
            not validated on the way out, so treat an unfamiliar value as opaque
            rather than an error.
          example: live_transfer
        agentType:
          type:
            - string
            - 'null'
          enum:
            - appointment_confirmation
            - appointment_booking
            - live_transfer
            - live_transfer_and_tag
            - live_transfer_and_booking
            - add_tag
            - inbound_receptionist
            - null
          deprecated: true
          description: >-
            This module still speaks the seven legacy V2 template ids, so the
            value here is the same one as `system`, not the three-value campaign
            type the Agents module publishes. Null when the campaign carries no
            recognised template. Prefer `agentType` on the Agents module
            (`outreach`, `inbound`, `appointment`) plus the campaign's
            capabilities.
          example: appointment_booking
        dialing:
          type:
            - string
            - 'null'
          enum:
            - s2l
            - pd
            - s2l_pd
            - confirmation
            - reactivation
            - null
          description: >-
            Dispatch mode. Two values are read-only. `confirmation` is what a
            Reminder campaign stores; note that List agents reports the same
            campaign as `pd`, so the two endpoints differ on this field.
            `reactivation` is retired and reads only: campaigns created before
            it was withdrawn still report it and still dial, but it can no
            longer be set on a create or an update. Only `s2l`, `pd`, and
            `s2l_pd` are writable.
          example: s2l_pd
        callingWindow:
          oneOf:
            - $ref: '#/components/schemas/CampaignsCallingWindow'
            - type: array
              items:
                $ref: '#/components/schemas/CampaignsCallingWindow'
            - type: 'null'
        multipleTimezoneCheck:
          type: boolean
          example: true
        dropOutsideWindow:
          type: boolean
          example: false
        config:
          $ref: '#/components/schemas/CampaignsConfig'
        fromNumbers:
          type: array
          items:
            type: string
          example:
            - '+14155551234'
        agencyName:
          type:
            - string
            - 'null'
          example: Acme Agency
        projectId:
          type:
            - string
            - 'null'
          description: Id of the project this campaign belongs to.
          example: proj_123
        locationId:
          type:
            - string
            - 'null'
          description: CRM location id of the project this campaign belongs to.
          example: loc_abc123
        businessName:
          type:
            - string
            - 'null'
          description: Visible business name of the project this campaign belongs to.
          example: Acme Roofing
        isActive:
          type: boolean
          deprecated: true
          description: >-
            Storage spelling of `active`, still emitted for clients written
            before the canonical names. Same value. Build on `active`.
          example: false
        type:
          type:
            - string
            - 'null'
          deprecated: true
          description: >-
            Storage spelling of `dialing`, still emitted for clients written
            before the canonical names. Same value. Build on `dialing`.
          example: s2l_pd
        createdAt:
          type: string
          format: date-time
          example: '2026-07-08T16:20:00.000Z'
        updatedAt:
          type: string
          format: date-time
          example: '2026-07-08T16:30:00.000Z'
    CampaignsTransferRoute:
      type: object
      additionalProperties: false
      required:
        - id
        - number
        - condition
      properties:
        id:
          type: string
          example: route_sales
        number:
          type: string
          example: '+14155550100'
        condition:
          type: string
          example: Use for pricing or booking questions.
    AgentsFillerWords:
      type: object
      additionalProperties: false
      description: >-
        Filler words the agent uses in its OWN speech, compiled into the agent
        prompt. Distinct from backchannelWords, which the voice stack speaks
        over the caller. Each key is optional; omitted keys keep their stored
        value.
      properties:
        enabled:
          type: boolean
          example: true
        words:
          type: array
          items:
            type: string
          description: >-
            Up to 30 entries, 40 characters each. Trimmed and deduped
            server-side.
          example:
            - um
            - so
            - you know
        examples:
          type: object
          additionalProperties:
            type: string
            maxLength: 200
          description: >-
            Example sentences keyed by word, showing how the agent should use
            it. Required for a word outside the built-in dictionary — the
            example supplies the placement the dictionary would otherwise
            provide — and optional for a known word, where it replaces the stock
            example. Keys are normalised (lowercased, apostrophes dropped) and
            entries for unselected words are pruned.
          example:
            innit: Proper busy today, innit.
    AgentsOutcomes:
      type: object
      additionalProperties: false
      description: >-
        The four editable call outcomes, each mapped to the prompt that decides
        it.
      properties:
        opt_out:
          type: string
          example: The lead explicitly asked not to be contacted again.
        callback:
          type: string
          example: The lead asked to be called back at a later time.
        human_needed:
          type: string
          example: A human team member needs to review or follow up.
        asked_for_info:
          type: string
          example: The lead asked to receive additional information.
    AgentsCustomField:
      type: object
      additionalProperties: false
      required:
        - key
        - type
        - prompt
      properties:
        key:
          type: string
          description: Stable machine name for the extracted field.
          example: customer_name
        type:
          type: string
          enum:
            - text
            - choice
            - number
            - boolean
          description: >-
            Field kind. Use "choice" with `options`; "text" may carry
            `examples`.
          example: text
        prompt:
          type: string
          description: What the model should extract from the call.
          example: The full name of the lead.
        options:
          type: array
          items:
            type: string
          description: Allowed values. Required when `type` is "choice".
          example:
            - booked
            - not_booked
        examples:
          type: array
          items:
            type: string
          description: Example values to steer extraction. Applies to "text".
          example:
            - Jane Smith
        extractWhen:
          type: string
          description: Only extract this field when the condition holds.
          example: The lead agreed to book an appointment.
        required:
          type: boolean
          example: false
    AgentsConfigAgent:
      type: object
      additionalProperties: {}
      properties:
        agentName:
          type: string
          description: Current display name for the agent.
          example: Roofing Follow Up
    AgentsConfigPrompt:
      type: object
      additionalProperties: {}
      properties:
        generalPrompt:
          type: string
          description: >-
            Operator-visible prompt context. Protected platform layers are
            removed from API responses.
          example: |-
            # Context
            Qualify the lead and book an appointment.
        beginMessage:
          type: string
          description: First message the agent says when the call starts.
          example: Hi, this is Sarah from Acme Roofing.
    AgentsConfigVoice:
      type: object
      additionalProperties: {}
      properties:
        voiceId:
          type: string
          example: custom_voice_d7515c44b4aaea0ceade0a37ae
        ambientSound:
          type:
            - string
            - 'null'
          enum:
            - coffee-shop
            - convention-hall
            - summer-outdoor
            - mountain-outdoor
            - static-noise
            - call-center
            - null
          description: Optional background ambience.
          example: null
        ambientSoundVolume:
          type:
            - number
            - 'null'
          minimum: 0
          maximum: 2
          description: >-
            How loud the ambient sound sits under the voice. 1 is the standard
            level, 0 mutes it.
          example: 0.75
        temperature:
          type: number
          minimum: 0
          maximum: 2
          description: Voice expressiveness.
          example: 0.8
        speed:
          type: number
          minimum: 0.5
          maximum: 2
          description: Voice speaking pace. 1 is normal speed.
          example: 1
    AgentsConfigInteraction:
      type: object
      additionalProperties: {}
      properties:
        enableBackchannel:
          type: boolean
          description: >-
            Whether the agent may use short acknowledgement words while
            listening.
          example: true
        backchannelFrequency:
          type:
            - number
            - 'null'
          minimum: 0
          maximum: 1
          description: Backchannel frequency from 0 to 1.
          example: 0.6
        backchannelWords:
          type: array
          items:
            type: string
          example:
            - yeah
            - got it
        fillerWords:
          $ref: '#/components/schemas/AgentsFillerWords'
    AgentsConfigLanguage:
      type: object
      additionalProperties: {}
      properties:
        language:
          oneOf:
            - type: string
              example: en-US
            - type: array
              items:
                type: string
              example:
                - en-US
                - es-ES
          description: >-
            Speech recognition locale or ordered locales for multilingual
            agents.
        denoisingMode:
          type: string
          enum:
            - no-denoise
            - noise-cancellation
            - noise-and-background-speech-cancellation
          example: noise-cancellation
    AgentsAnalysis:
      type: object
      additionalProperties: {}
      description: >-
        Post-call analysis, split into the editable outcomes, your custom
        fields, and the read-only names of the platform-managed fields.
      properties:
        outcomes:
          $ref: '#/components/schemas/AgentsOutcomes'
        fields:
          type: array
          items:
            $ref: '#/components/schemas/AgentsCustomField'
        locked:
          type: array
          items:
            type: string
          description: >-
            Read-only names of the platform-managed fields the server always
            keeps.
          example:
            - call_summary
            - call_successful
  securitySchemes:
    ApiKeyAuth:
      type: http
      scheme: bearer
      bearerFormat: API key
      description: 'Send your API key as `Authorization: Bearer YOUR_API_KEY`.'

````