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

# Finalize Campaign

> Atomically save all campaign editor state (fields, questions, contacts).

Replaces existing questions and contacts to stay in sync with the
frontend editor state. Called before navigating to the review page.



## OpenAPI

````yaml /openapi.json put /v1/campaign-creation/{interview_id}/finalize
openapi: 3.1.0
info:
  title: Ontora API
  description: >-
    Ontora's public API. Covers interview campaigns, transcripts, synthesis
    reports, graph queries, webhooks, and workspace management. 


    **Authentication**: endpoints accept either a Clerk JWT (`Authorization:
    Bearer <token>`) or a workspace API key (`X-API-Key: ont_...`). Workspace
    keys are managed via `/v1/api-keys`.
  version: 0.1.0
servers: []
security:
  - ClerkJWT: []
  - WorkspaceApiKey: []
tags:
  - name: interviews
    description: Campaign CRUD, lifecycle, contacts, question sets.
  - name: campaign-insights
    description: Synthesis outputs — cartography, roadmap, personas, conversations.
  - name: interview-query
    description: Graph RAG query over campaign data.
  - name: interview-export
    description: Markdown / ZIP exports of transcripts and reports.
  - name: api-keys
    description: Manage workspace-scoped API keys for programmatic access.
  - name: webhook-endpoints
    description: Outbound webhook endpoints for automation.
  - name: booking
    description: Public self-scheduling endpoints for interview participants.
  - name: workspaces
    description: Workspace and membership management.
  - name: vaults
    description: Context vault management.
paths:
  /v1/campaign-creation/{interview_id}/finalize:
    put:
      tags:
        - campaign-creation
      summary: Finalize Campaign
      description: |-
        Atomically save all campaign editor state (fields, questions, contacts).

        Replaces existing questions and contacts to stay in sync with the
        frontend editor state. Called before navigating to the review page.
      operationId: finalize_campaign_v1_campaign_creation__interview_id__finalize_put
      parameters:
        - name: interview_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
            title: Interview Id
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FinalizeCampaignRequest'
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
      security:
        - HTTPBearer: []
components:
  schemas:
    FinalizeCampaignRequest:
      properties:
        name:
          anyOf:
            - type: string
            - type: 'null'
          title: Name
        description:
          anyOf:
            - type: string
            - type: 'null'
          title: Description
        goal:
          anyOf:
            - type: string
            - type: 'null'
          title: Goal
        interview_context_for_employee:
          anyOf:
            - type: string
            - type: 'null'
          title: Interview Context For Employee
        success_criteria:
          anyOf:
            - type: string
            - type: 'null'
          title: Success Criteria
        agent_behavior:
          anyOf:
            - type: string
            - type: 'null'
          title: Agent Behavior
        interview_type:
          anyOf:
            - type: string
            - type: 'null'
          title: Interview Type
        voice_id:
          anyOf:
            - type: string
            - type: 'null'
          title: Voice Id
        channel:
          anyOf:
            - type: string
            - type: 'null'
          title: Channel
        welcome_screen:
          anyOf:
            - type: string
            - type: 'null'
          title: Welcome Screen
        closing_message:
          anyOf:
            - type: string
            - type: 'null'
          title: Closing Message
        recurring_interval:
          anyOf:
            - type: string
            - type: 'null'
          title: Recurring Interval
        interview_duration_minutes:
          anyOf:
            - type: integer
            - type: 'null'
          title: Interview Duration Minutes
        timeframe_start:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Timeframe Start
        timeframe_end:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Timeframe End
        quick_mode_hours:
          anyOf:
            - type: integer
            - type: 'null'
          title: Quick Mode Hours
        scheduling_mode:
          anyOf:
            - type: string
            - type: 'null'
          title: Scheduling Mode
        start_immediately:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Start Immediately
        followup_enabled:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Followup Enabled
        followup_strategy:
          anyOf:
            - type: string
            - type: 'null'
          title: Followup Strategy
        followup_intervals_hours:
          anyOf:
            - items:
                type: integer
              type: array
            - type: 'null'
          title: Followup Intervals Hours
        followup_deadline_days:
          anyOf:
            - items:
                type: integer
              type: array
            - type: 'null'
          title: Followup Deadline Days
        followup_message:
          anyOf:
            - type: string
            - type: 'null'
          title: Followup Message
        topics:
          items:
            $ref: '#/components/schemas/FinalizeTopicIn'
          type: array
          title: Topics
          default: []
        questions:
          items:
            $ref: '#/components/schemas/FinalizeQuestionIn'
          type: array
          title: Questions
          default: []
        contacts:
          items:
            $ref: '#/components/schemas/FinalizeContactIn'
          type: array
          title: Contacts
          default: []
      type: object
      title: FinalizeCampaignRequest
      description: Full campaign save — persists all editor state atomically.
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    FinalizeTopicIn:
      properties:
        name:
          type: string
          title: Name
        goal:
          type: string
          title: Goal
          default: ''
        success_threshold:
          type: string
          title: Success Threshold
          default: ''
        priority:
          type: string
          title: Priority
          default: important
        sub_topics:
          items:
            type: string
          type: array
          title: Sub Topics
          default: []
        questions:
          items:
            $ref: '#/components/schemas/FinalizeQuestionIn'
          type: array
          title: Questions
          default: []
      type: object
      required:
        - name
      title: FinalizeTopicIn
    FinalizeQuestionIn:
      properties:
        text:
          type: string
          title: Text
        is_required:
          type: boolean
          title: Is Required
          default: true
      type: object
      required:
        - text
      title: FinalizeQuestionIn
    FinalizeContactIn:
      properties:
        name:
          type: string
          title: Name
        email:
          anyOf:
            - type: string
            - type: 'null'
          title: Email
        phone:
          anyOf:
            - type: string
            - type: 'null'
          title: Phone
        job_title:
          anyOf:
            - type: string
            - type: 'null'
          title: Job Title
        department:
          anyOf:
            - type: string
            - type: 'null'
          title: Department
        seniority_level:
          anyOf:
            - type: integer
            - type: 'null'
          title: Seniority Level
        is_required:
          type: boolean
          title: Is Required
          default: false
      type: object
      required:
        - name
      title: FinalizeContactIn
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
              - type: string
              - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
        input:
          title: Input
        ctx:
          type: object
          title: Context
      type: object
      required:
        - loc
        - msg
        - type
      title: ValidationError
  securitySchemes:
    ClerkJWT:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: Clerk-issued RS256 JWT.
    WorkspaceApiKey:
      type: apiKey
      in: header
      name: X-API-Key
      description: 'Workspace-scoped API key (prefix: `ont_`).'
    HTTPBearer:
      type: http
      scheme: bearer

````