---
title: "Create Agent Variant"
method: POST
path: "/agent-variants/"
tags: ["authenticated", "agent-variants"]
---

# Create Agent Variant

`POST /agent-variants/`

## Request

- Base URL: `https://api-docs.upsmith.com` (the document declares no server; this is the origin it was published from)
- URL: `https://api-docs.upsmith.com/agent-variants/`
- Auth: one of:
  - API key in header `x-api-key`
  - HTTP bearer

## Headers

- `timezone` string
- `x-user-id` string, nullable
- `x-actor-email` string, nullable
- `x-request-source` string, nullable
- `x-operation-id` string, nullable
- `x-commit-message` string, nullable
- `x-confirmation-id` string, nullable
- `x-chat-id` string, nullable
- `organization-id` string, nullable

## Request body

- CreateAgentVariantBody
  - `agent_v2_id` string, required
  - `mlflow_persona_prompt` string, required
  - `model` string, nullable
  - `voice_settings` AgentVariantVoiceSettings
    - `v3_csr_canonical` VoiceV3CsrCanonicalSettings
      - `voice_id` unknown
      - `speed` number, nullable
      - `stability` unknown
      - `similarity_boost` unknown
      - `use_speaker_boost` unknown
      - `semantic_vad_eagerness` 'auto' | 'low' | 'medium' | 'high'
      - `transfer_destinations` ConfiguredTransferDestination[], nullable
        - `name` string, required
        - `phone_number` string, required
        - `reason` string, required
        - `schedule` CsrOfficeSchedule
          - `timezone` string, required
          - `closed_dates` string[]
          - `mon` CsrOfficeInterval[], required
            - `start_minute` integer, required
            - `end_minute` integer, required
          - `tue` CsrOfficeInterval[], required
            - `start_minute` integer, required
            - `end_minute` integer, required
          - `wed` CsrOfficeInterval[], required
            - `start_minute` integer, required
            - `end_minute` integer, required
          - `thu` CsrOfficeInterval[], required
            - `start_minute` integer, required
            - `end_minute` integer, required
          - `fri` CsrOfficeInterval[], required
            - `start_minute` integer, required
            - `end_minute` integer, required
          - `sat` CsrOfficeInterval[], required
            - `start_minute` integer, required
            - `end_minute` integer, required
          - `sun` CsrOfficeInterval[], required
            - `start_minute` integer, required
            - `end_minute` integer, required
          - `breaks_open` boolean
      - `csr_config` CsrPromptConfig, required
        - `warranty_source_scheduling` boolean
        - `enabled_tools` string[], nullable
        - `organization` OrganizationPromptConfig
          - `safety_policy` CsrSafetyPolicy
            - `direction` LocalizedText, required
              - …
            - `resume_assistance` boolean
            - `water_shutoff` CsrWaterShutoffPolicy
              - …
            - `emergency_transfer_destination` string, nullable
          - `company_name` string, nullable
          - `agent_name` string, nullable
          - `organization_guidance` CsrOrganizationGuidance
            - `after_hours_staff_managed_emergency_fee_minor` integer, nullable
            - `mention_possible_emergency_charge` boolean
            - `emergency_follow_up_only` boolean
            - `instructions` string[]
          - `conversation` CsrConversationPolicy
            - `voice` 'first_party_team'
            - `empathy` 'situational_once' | 'brief_neutral'
            - `pronunciations` CsrPronunciation[]
              - …
            - `localized_content` CsrLocalizedOverride[]
              - …
          - `opening` CsrOpeningPolicy, required
            - `default` CsrOpeningVariants, required
              - …
            - `known_caller` CsrOpeningVariants
              - …
            - `recording` 'in_greeting' | 'not_required', required
          - `information` CsrInformationPolicy
            - `topics` CsrInformationTopic[], required
              - …
          - `concerns` CsrConcernPolicy
            - `intents` string[]
            - `opening` 'thank_empathize_then_question'
            - `intake_rule_keys` string[], required
            - `summary_components` string[], required
            - `owner_key` string, required
            - `reflect_back` boolean
          - `related_brands` CsrRelatedBrandsPolicy: Display only: naming one of these brands selects no route and no pricing.
            - `brands` CsrRelatedBrand[], required
              - …
            - `explanation` LocalizedText
              - …
            - `speak_when` 'caller_names_brand' | 'asked_about_company'
          - `safety_screen` CsrSafetyScreenPolicy
            - `mode` 'reactive' | 'before_booking_once', required
            - `question` LocalizedText
              - …
          - `quote_policy` CsrQuotePolicy
            - `membership_authority` CsrMembershipAuthority
              - …
            - `rules` CsrQuoteRule[], required
              - …
            - `unresolved` 'staff_confirms_no_quote', required
          - `disclosure_plan` CsrDisclosurePlan
            - `entries` CsrDisclosureEntry[], required
              - …
          - `answer_service_coverage_questions` boolean
          - `disclosures` CsrDisclosureConfig, required
            - `recording` string, nullable
          - `service_address` CsrAddressCollectionConfig, required
            - `question` string, required
            - `known_location_question` string, nullable
            - `confirmation` string, required
            - `required_components` string[], required
          - `email` CsrEmailCollectionConfig, required
            - `action` 'skip' | 'collect_only' | 'save_confirmed', required
            - `question` string, required
            - `known_email_question` string, nullable
            - `confirmation` string, required
            - `required_before_booking` boolean, nullable
          - `callback` CsrCallbackConfig, required
            - `confirm_inbound_number` boolean, required
            - `allow_alternate` boolean, required
          - `intake` CsrIntakeConfig, required
            - `warranty_source_scheduling` boolean
            - `request_intake` CsrRequestIntakePolicy
              - …
            - `ask_timing_preference` boolean, required
            - `required_service_details` string[]
            - `new_booking_qualification` CsrNewBookingQualificationConfig
              - …
          - `scheduling` CsrSchedulingConfig, required
            - `preferences` CsrTimingPreferencePolicy
              - …
            - `no_availability_action` 'collect_preference' | 'transfer' | 'follow_up', required
            - `new_booking_contract` CsrNewBookingContract
              - …
          - `membership` CsrMembershipConfig
            - `lookup` boolean, required
            - `disclosure` string, nullable
            - `offer` string, nullable
            - `decline_limit` integer
          - `existing_appointments` CsrExistingAppointmentsConfig
            - `status_lookup` boolean
            - `reschedule` 'disabled' | 'offer_staff_follow_up' | 'enabled'
            - `reschedule_job_type_ids` integer[], nullable: Only these job types may be rescheduled directly; other or unknown types require staff. Omit to allow all eligible types.
            - `cancel` 'disabled' | 'offer_staff_follow_up'
            - `confirm` 'disabled' | 'offer_staff_follow_up' | 'direct'
          - `fee` CsrFeeConfig
            - `amount_minor` integer, required
            - `currency` 'USD' | 'CAD', required
            - `taxable` boolean, required
            - `applicability` 'all_calls' | 'non_members' | 'selected_services', required
            - `disclosure` string, required
            - `requires_acceptance` boolean
            - `disclosure_phase` 'before_booking' | 'after_booking', nullable
            - `label` string
            - `rationale` string, nullable
          - `membership_fees` CsrMembershipFeePolicy
            - `rules` CsrMembershipFeeRule[], required
              - …
            - `source` 'scoped_service_titan_mirror', required
            - `classification` 'active_at_booking_v1', required
            - `phase` 'before_booking'
            - `unmatched` 'unresolved'
          - `document_fees` CsrDocumentFeePolicy
            - `document_titles` string[], required
            - `disclosure_phase` 'before_availability' | 'before_booking' | 'after_booking'
            - `requires_acceptance` boolean
            - `membership_pricing` boolean
            - `unverified_membership` 'staff_review' | 'nonmember_fee'
            - `record_unverified_membership_claim` boolean
          - `intake_fees` CsrIntakeFeePolicy
            - `field_key` string, required
            - `categories` CsrIntakeFeeCategory[], required
              - …
            - `rules` CsrIntakeFeeRule[], required
              - …
            - `unmatched` 'unresolved'
          - `follow_up_submission` CsrFollowUpSubmissionPolicy
            - `mode` 'exact_later_turn_v1', required
            - `include_emergency` boolean
            - `emergency_failure` CsrEmergencyFollowUpFailurePolicy
              - …
          - `priority_booking` CsrPriorityBookingPolicy
            - `emergency` CsrEmergencyBookingPolicy, required
              - …
            - `high_value` CsrHighValueBookingPolicy, required: How an entitled organization decides a job is worth overbooking a full day for. Exactly one of the two routes qualifies a job. ``criteria`` narrows deterministically from recorded intake answers, so the runtime decides and the model cannot widen it. ``any_demand_call_v1`` hands that judgment to the model instead: every caller with a problem right now qualifies, which no condition over declared intake fields can express. Mixing them would leave both the prompt and the booking evidence without a single rule to state.
              - …
            - `unavailable_action` 'transfer' | 'follow_up', required
            - `transfer_destination_name` string, nullable
            - `transfer_failure_action` 'report_failure' | 'offer_follow_up', nullable
          - `routing` CsrRoutingConfig, required
            - `request_policy` CsrRequestRoutingPolicy
              - …
            - `follow_up_owners` CsrFollowUpOwner[]
              - …
            - `office_open` 'transfer' | 'follow_up' | 'emergency_services' | 'end_call', required
            - `office_closed` 'transfer' | 'follow_up' | 'emergency_services' | 'end_call', required
            - `urgent` 'transfer' | 'follow_up' | 'emergency_services' | 'end_call', required
            - `emergency` 'transfer' | 'follow_up' | 'emergency_services' | 'end_call', required
          - `closing` CsrClosingConfig, required
            - `additional_help_question` string, required
            - `farewell` string, required
            - `spanish_farewell` string, nullable
          - `credibility_statements` string[]
        - `reschedule_policy` 'enabled', nullable
        - `reschedule_job_type_ids` integer[], nullable
        - `timing_preference_policy` CsrTimingPreferencePolicy
          - `mode` 'volunteered_only' | 'ask_day_or_soonest' | 'ask_day_and_unavailable_times', required
          - `day_question` string, nullable
          - `unavailable_times_question` string, nullable
          - `stage` 'before_availability'
    - `live` VoiceLiveSettings
      - `intro` VoiceLiveIntroSettings, required
        - `company_name` string, nullable
        - `agent_name` string, nullable
        - `opening` CsrOpeningPolicy, required
          - `default` CsrOpeningVariants, required
            - `open` CsrPhrase, required
              - …
            - `closed` CsrPhrase, required
              - …
            - `unknown` CsrPhrase, required
              - …
          - `known_caller` CsrOpeningVariants
            - `open` CsrPhrase, required
              - …
            - `closed` CsrPhrase, required
              - …
            - `unknown` CsrPhrase, required
              - …
          - `recording` 'in_greeting' | 'not_required', required
        - `disclosures` CsrDisclosureConfig, required
          - `recording` string, nullable
      - `voice` 'alloy' | 'ash' | 'ballad' | 'beacon' | 'bossa' | 'cedar' | 'cinder' | 'coral' | 'delta' | 'echo' | 'gleam' | 'marin' | 'meridian' | 'quartz' | 'ripple' | 'sage' | 'shida' | 'shimmer' | 'stone' | 'tempo' | 'verse' | 'vesper' | 'willow', nullable
  - `composition_instructions` string, nullable
  - `prompt_variables` object[], nullable
  - `system_prompt_components` SystemPromptComponentReference[], nullable
    - `prompt_name` string, required
    - `prompt_version` string, required
    - `parameters` object
  - `roster_id` string, nullable
  - `description` string, nullable
  - `objectives` VariantObjectiveInput[]
    - `objective_id` string, required
    - `sort_order` integer
  - `hooks` VariantHookInput[]
    - `hook_id` string, required

## Response `200`

Successful Response

- object

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/upsmith/apis/upsmith-api.md) - [All operations](https://skmtc.dev/upsmith/apis/upsmith-api/llms.txt) - [OpenAPI document](https://skmtc.dev/upsmith/apis/upsmith-api/revisions/86e2c2bd93af?raw)
