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

# Create Campaign

> Create a new outbound calling campaign

Before creating a campaign, [upload your contacts CSV](/api-reference/campaigns/upload-contacts) to get a `source_url`.

Set `telephony_configuration_id` to pin the campaign to a specific [telephony configuration](/api-reference/telephony-configs). If omitted, Bananaflow falls back to the organization's [default outbound configuration](/api-reference/telephony-configs/set-default-outbound) – supplying an id that doesn't exist in your organization returns `400 telephony_configuration_not_found`.

The `time_slots` field controls when Bananaflow is allowed to place calls. If omitted, calls can be placed at any time. The `timezone` field applies to all time slot windows.

```json theme={null}
{
  "time_slots": [
    { "day": "monday", "start": "09:00", "end": "17:00" },
    { "day": "tuesday", "start": "09:00", "end": "17:00" }
  ]
}
```

Once created, the campaign is in `draft` status. Call [Start](/api-reference/campaigns/start) to begin dialing.

To split calls between agents or versions, send `traffic_split` instead of `workflow_id`:

```json theme={null}
{
  "name": "Version comparison",
  "source_type": "csv",
  "source_id": "your-uploaded-csv-key",
  "traffic_split": {
    "variants": [
      { "workflow_id": 12, "workflow_definition_id": null, "weight": 50 },
      { "workflow_id": 12, "workflow_definition_id": 341, "weight": 50 }
    ]
  }
}
```

You can specify one to five unique agent/version pairs. Weights must be whole percentages from 1 to 100 and total 100. All agents must belong to your organization, and your CSV must supply the template variables required by every selected version.

Omit `workflow_definition_id` or set it to `null` to use the latest published version at dial time. A definition ID pins a published or archived version; drafts cannot be selected. Calls already in progress keep their version.

You can change the split with `PATCH /api/v1/campaign/{campaign_id}` while a campaign is running or paused. Changes apply to the next batch, including retries. A contact stays on the same variant while the split is unchanged; changing weights or removing variants can move contacts. Reordering existing variants alone does not change allocation. Redial campaigns inherit the current split and its allocation seed.

The campaign detail page shows current target percentages and actual shares across all attempts, including retries and earlier splits. Shares are approximate, especially with small contact lists. `GET /api/v1/campaign/{campaign_id}/traffic-stats` returns the same counts, outcomes, and versions used, including variants removed from the current split.


## OpenAPI

````yaml POST /api/v1/campaign/create
openapi: 3.1.0
info:
  title: Bananaflow API
  description: API for the Bananaflow app
  version: 1.0.0
servers:
  - url: https://app.bananaflow.ai
    description: Production
security: []
paths:
  /api/v1/campaign/create:
    post:
      tags:
        - main
      summary: Create Campaign
      description: Create a new campaign
      operationId: create_campaign_api_v1_campaign_create_post
      parameters:
        - name: authorization
          in: header
          required: false
          schema:
            anyOf:
              - type: string
              - type: 'null'
            title: Authorization
        - name: X-API-Key
          in: header
          required: false
          schema:
            anyOf:
              - type: string
              - type: 'null'
            title: X-Api-Key
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateCampaignRequest'
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CampaignResponse'
        '404':
          description: Not found
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
components:
  schemas:
    CreateCampaignRequest:
      properties:
        name:
          type: string
          maxLength: 255
          minLength: 1
          title: Name
        workflow_id:
          anyOf:
            - type: integer
              exclusiveMinimum: 0
            - type: 'null'
          title: Workflow Id
        traffic_split:
          anyOf:
            - $ref: '#/components/schemas/TrafficSplitRequest'
            - type: 'null'
        source_type:
          type: string
          pattern: ^csv$
          title: Source Type
        source_id:
          type: string
          title: Source Id
        telephony_configuration_id:
          anyOf:
            - type: integer
            - type: 'null'
          title: Telephony Configuration Id
        retry_config:
          anyOf:
            - $ref: '#/components/schemas/RetryConfigRequest'
            - type: 'null'
        max_concurrency:
          anyOf:
            - type: integer
              minimum: 1
            - type: 'null'
          title: Max Concurrency
        rate_limit_per_second:
          type: integer
          minimum: 1
          title: Rate Limit Per Second
          default: 1
        schedule_config:
          anyOf:
            - $ref: '#/components/schemas/ScheduleConfigRequest'
            - type: 'null'
        circuit_breaker:
          anyOf:
            - $ref: '#/components/schemas/CircuitBreakerConfigRequest'
            - type: 'null'
      type: object
      required:
        - name
        - source_type
        - source_id
      title: CreateCampaignRequest
    CampaignResponse:
      properties:
        traffic_split:
          anyOf:
            - $ref: '#/components/schemas/TrafficSplitResponse'
            - type: 'null'
        id:
          type: integer
          title: Id
        name:
          type: string
          title: Name
        workflow_id:
          type: integer
          title: Workflow Id
        workflow_name:
          type: string
          title: Workflow Name
        state:
          type: string
          title: State
        source_type:
          type: string
          title: Source Type
        source_id:
          type: string
          title: Source Id
        total_rows:
          anyOf:
            - type: integer
            - type: 'null'
          title: Total Rows
        processed_rows:
          type: integer
          title: Processed Rows
        failed_rows:
          type: integer
          title: Failed Rows
        created_at:
          type: string
          format: date-time
          title: Created At
        started_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Started At
        completed_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Completed At
        retry_config:
          $ref: '#/components/schemas/RetryConfigResponse'
        max_concurrency:
          anyOf:
            - type: integer
            - type: 'null'
          title: Max Concurrency
        rate_limit_per_second:
          type: integer
          title: Rate Limit Per Second
          default: 1
        schedule_config:
          anyOf:
            - $ref: '#/components/schemas/ScheduleConfigResponse'
            - type: 'null'
        circuit_breaker:
          anyOf:
            - $ref: '#/components/schemas/CircuitBreakerConfigResponse'
            - type: 'null'
        executed_count:
          type: integer
          title: Executed Count
          default: 0
        total_queued_count:
          type: integer
          title: Total Queued Count
          default: 0
        parent_campaign_id:
          anyOf:
            - type: integer
            - type: 'null'
          title: Parent Campaign Id
        redialed_campaign_id:
          anyOf:
            - type: integer
            - type: 'null'
          title: Redialed Campaign Id
        telephony_configuration_id:
          anyOf:
            - type: integer
            - type: 'null'
          title: Telephony Configuration Id
        telephony_configuration_name:
          anyOf:
            - type: string
            - type: 'null'
          title: Telephony Configuration Name
        logs:
          items:
            $ref: '#/components/schemas/CampaignLogEntryResponse'
          type: array
          title: Logs
        warnings:
          items:
            type: string
          type: array
          title: Warnings
      type: object
      required:
        - id
        - name
        - workflow_id
        - workflow_name
        - state
        - source_type
        - source_id
        - total_rows
        - processed_rows
        - failed_rows
        - created_at
        - started_at
        - completed_at
        - retry_config
      title: CampaignResponse
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    TrafficSplitRequest:
      properties:
        variants:
          items:
            $ref: '#/components/schemas/TrafficVariantRequest'
          type: array
          maxItems: 5
          minItems: 1
          title: Variants
      type: object
      required:
        - variants
      title: TrafficSplitRequest
    RetryConfigRequest:
      properties:
        enabled:
          type: boolean
          title: Enabled
          default: true
        max_retries:
          type: integer
          maximum: 10
          minimum: 0
          title: Max Retries
          default: 2
        retry_delay_seconds:
          type: integer
          maximum: 3600
          minimum: 30
          title: Retry Delay Seconds
          default: 120
        retry_on_busy:
          type: boolean
          title: Retry On Busy
          default: true
        retry_on_no_answer:
          type: boolean
          title: Retry On No Answer
          default: true
        retry_on_voicemail:
          type: boolean
          title: Retry On Voicemail
          default: true
      type: object
      title: RetryConfigRequest
    ScheduleConfigRequest:
      properties:
        enabled:
          type: boolean
          title: Enabled
          default: true
        timezone:
          type: string
          title: Timezone
          default: UTC
        slots:
          items:
            $ref: '#/components/schemas/TimeSlotRequest'
          type: array
          maxItems: 50
          minItems: 1
          title: Slots
      type: object
      required:
        - slots
      title: ScheduleConfigRequest
    CircuitBreakerConfigRequest:
      properties:
        enabled:
          type: boolean
          title: Enabled
          default: true
        failure_threshold:
          type: number
          maximum: 1
          minimum: 0
          title: Failure Threshold
          default: 0.5
        window_seconds:
          type: integer
          maximum: 600
          minimum: 30
          title: Window Seconds
          default: 120
        min_calls_in_window:
          type: integer
          maximum: 100
          minimum: 1
          title: Min Calls In Window
          default: 5
      type: object
      title: CircuitBreakerConfigRequest
    TrafficSplitResponse:
      properties:
        revision:
          type: integer
          title: Revision
        variants:
          items:
            $ref: '#/components/schemas/TrafficVariantResponse'
          type: array
          title: Variants
      type: object
      required:
        - revision
        - variants
      title: TrafficSplitResponse
    RetryConfigResponse:
      properties:
        enabled:
          type: boolean
          title: Enabled
        max_retries:
          type: integer
          title: Max Retries
        retry_delay_seconds:
          type: integer
          title: Retry Delay Seconds
        retry_on_busy:
          type: boolean
          title: Retry On Busy
        retry_on_no_answer:
          type: boolean
          title: Retry On No Answer
        retry_on_voicemail:
          type: boolean
          title: Retry On Voicemail
      type: object
      required:
        - enabled
        - max_retries
        - retry_delay_seconds
        - retry_on_busy
        - retry_on_no_answer
        - retry_on_voicemail
      title: RetryConfigResponse
    ScheduleConfigResponse:
      properties:
        enabled:
          type: boolean
          title: Enabled
        timezone:
          type: string
          title: Timezone
        slots:
          items:
            $ref: '#/components/schemas/TimeSlotResponse'
          type: array
          title: Slots
      type: object
      required:
        - enabled
        - timezone
        - slots
      title: ScheduleConfigResponse
    CircuitBreakerConfigResponse:
      properties:
        enabled:
          type: boolean
          title: Enabled
          default: false
        failure_threshold:
          type: number
          title: Failure Threshold
          default: 0.5
        window_seconds:
          type: integer
          title: Window Seconds
          default: 120
        min_calls_in_window:
          type: integer
          title: Min Calls In Window
          default: 5
      type: object
      title: CircuitBreakerConfigResponse
    CampaignLogEntryResponse:
      properties:
        ts:
          type: string
          title: Ts
        level:
          type: string
          title: Level
        event:
          type: string
          title: Event
        message:
          type: string
          title: Message
        details:
          anyOf:
            - additionalProperties: true
              type: object
            - type: 'null'
          title: Details
      type: object
      required:
        - ts
        - level
        - event
        - message
      title: CampaignLogEntryResponse
      description: |-
        A single timestamped entry from the campaign's append-only log.

        Surfaced in the UI so operators can see why a campaign moved to
        paused / failed without digging through server logs.
    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
    TrafficVariantRequest:
      properties:
        workflow_id:
          type: integer
          exclusiveMinimum: 0
          title: Workflow Id
        workflow_definition_id:
          anyOf:
            - type: integer
              exclusiveMinimum: 0
            - type: 'null'
          title: Workflow Definition Id
        weight:
          type: integer
          maximum: 100
          minimum: 1
          title: Weight
      type: object
      required:
        - workflow_id
        - weight
      title: TrafficVariantRequest
    TimeSlotRequest:
      properties:
        day_of_week:
          type: integer
          maximum: 6
          minimum: 0
          title: Day Of Week
        start_time:
          type: string
          pattern: ^\d{2}:\d{2}$
          title: Start Time
        end_time:
          type: string
          pattern: ^\d{2}:\d{2}$
          title: End Time
      type: object
      required:
        - day_of_week
        - start_time
        - end_time
      title: TimeSlotRequest
    TrafficVariantResponse:
      properties:
        workflow_id:
          type: integer
          exclusiveMinimum: 0
          title: Workflow Id
        workflow_definition_id:
          anyOf:
            - type: integer
              exclusiveMinimum: 0
            - type: 'null'
          title: Workflow Definition Id
        weight:
          type: integer
          maximum: 100
          minimum: 1
          title: Weight
        id:
          type: string
          title: Id
        workflow_name:
          type: string
          title: Workflow Name
        version_number:
          anyOf:
            - type: integer
            - type: 'null'
          title: Version Number
      type: object
      required:
        - workflow_id
        - weight
        - id
        - workflow_name
      title: TrafficVariantResponse
    TimeSlotResponse:
      properties:
        day_of_week:
          type: integer
          title: Day Of Week
        start_time:
          type: string
          title: Start Time
        end_time:
          type: string
          title: End Time
      type: object
      required:
        - day_of_week
        - start_time
        - end_time
      title: TimeSlotResponse

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.