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

# Create Draft Outbound

> Create a new draft Outbound execution seeded with a minimal default sequence.

**CLI:**

```bash theme={null}
puffle campaign create
puffle campaign create --type <type> --name <name> --sender-account-ids <sender-account-ids> --skip-other-campaigns --operating-hours <operating-hours> --daily-limit <daily-limit> --stop-on-reply --open-tracking --signature <signature>
```

## Overview

Creates a `draft` campaign-backed Outbound execution for one channel (`linkedin` or `email`) and seeds it with a two-node default sequence: either `[connection_request, end]` or `[email, end]`. The draft is **not yet launchable**: the email body, contacts, and any extra nodes still need to be added.

## Prerequisites

You need at least one connected sender account that matches `type`:

* Get senders: `GET /api/senders?type=email` or `GET /api/senders?type=linkedin`
* If none exist, connect one first. Email setup uses [Create Email Account](/api-reference/senders/create-email-account); LinkedIn setup requires a human-operated dashboard connection flow.

## Typical follow-up sequence

1. `updateCampaign` - fill in `sequence_nodes` (for email, set `subject` and `body`; add more steps if needed)
2. `addLeadsToCampaign` - add at least one real recipient, or use `importLeadsFromListToCampaign` for a saved List
3. `getLeadsInCampaign` with `status=pending` - confirm the intended recipients were accepted and review the count
4. `getCampaign` with `id` - confirm the draft has matching sender accounts and non-empty sendable nodes
5. Ask the human to confirm the channel, sender, recipient count, and final sequence
6. `launchCampaign` - start sending only after that explicit confirmation

## AI agent notes

<Note>
  **Name uniqueness (409).** Names are unique per user. Retry with a suffix if you hit a 409.

  **Channel-specific fields.** LinkedIn-only fields (`skip_other_campaigns`, `operating_hours`) on an email draft and email-only fields (`daily_limit`, `stop_on_reply`, `open_tracking`, `signature`) on a LinkedIn draft are silently ignored, not rejected. Send only the fields that apply.

  **Default sequence is intentionally empty.** Email `subject` and `body` are empty strings. Populate them via `updateCampaign` or the AI message-generation flow before launch.

  **Sender accounts must match `type`.** A LinkedIn account id on an email draft, or vice versa, returns 400. Filter `GET /api/senders` by `type` before picking.

  **No contacts yet.** Creation seeds the sequence but adds no contacts. A launch attempt without pending contacts is rejected with `400` and `{ "error": "No leads in campaign" }`; the Outbound remains a draft. Add recipients and re-check the pending roster before asking for launch approval.
</Note>


## OpenAPI

````yaml post /api/campaigns
openapi: 3.0.3
info:
  title: Puffle API
  version: 1.0.0
  description: >-
    HTTP API for the Puffle GTM platform - Feed and Lead Finder search
    preparation, campaign-backed Outbound execution, Puffle Agent runs, sender
    management, and Unibox reply workflows. Designed for operation by both
    humans and autonomous AI agents. Agents should start at the [Agent
    Playbook](/guides/agent-playbook) which prescribes a workspace-context check
    (`GET /api/context`) and core user journeys with exact call ordering.
  contact:
    name: Puffle Support
    url: https://puffle.ai
servers:
  - url: https://app.puffle.ai
    description: Production
security:
  - bearerAuth: []
tags:
  - name: Campaigns
    description: >-
      Campaign-backed Outbound execution. These endpoints manage draft,
      launching, active, paused, and completed Outbound runs with sequence
      nodes, contacts, and sender accounts.
  - name: Accounts
    description: Signed-in user account, settings, and workspace context endpoints.
  - name: Billing
    description: Billing customer portal and account billing endpoints.
  - name: Senders
    description: >-
      Connected sender accounts, email inboxes, sending domains, DNS
      verification, warmup, and sender capacity.
  - name: Socials
    description: >-
      Read connected LinkedIn and X accounts, review current and archived posts,
      and reconcile publication status. Creating, editing, scheduling,
      publishing, OAuth connection, analytics, and mentions remain
      dashboard-managed workflows and are not part of the public Bearer-token
      API.
paths:
  /api/campaigns:
    post:
      tags:
        - Campaigns
      summary: Create Draft Outbound
      description: >-
        Create a new draft Outbound execution and seed it with the default
        sequence. Minimal drafts require only type; if name is blank or omitted,
        the API assigns the next available Untitled Outbound name. Sender
        accounts are optional at creation time.
      operationId: createDraftCampaign
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                type:
                  type: string
                name:
                  type: string
                sender_account_ids:
                  type: array
                  items:
                    type: string
                skip_other_campaigns:
                  type: boolean
                operating_hours:
                  type: object
                  additionalProperties: {}
                daily_limit:
                  type: number
                stop_on_reply:
                  type: boolean
                open_tracking:
                  type: boolean
                signature:
                  type: string
              additionalProperties: {}
      responses:
        '201':
          description: Outbound created as a draft with its seeded sequence.
          content:
            application/json:
              schema:
                type: object
                properties:
                  campaign:
                    type: object
                    properties:
                      id:
                        type: string
                        format: uuid
                      user_id:
                        type: string
                        format: uuid
                      type:
                        type: string
                        enum:
                          - linkedin
                          - email
                          - multi_channel
                      name:
                        type: string
                      status:
                        type: string
                        enum:
                          - draft
                          - launching
                          - active
                          - paused
                          - completed
                      daily_limit:
                        type: integer
                        exclusiveMinimum: true
                        maximum: 9007199254740991
                        nullable: true
                        minimum: 0
                      stop_on_reply:
                        type: boolean
                        nullable: true
                      open_tracking:
                        type: boolean
                        nullable: true
                      signature:
                        type: string
                        nullable: true
                      skip_other_campaigns:
                        type: boolean
                        nullable: true
                      operating_hours:
                        type: object
                        additionalProperties: {}
                        nullable: true
                      stats:
                        type: object
                        properties:
                          total:
                            type: integer
                            minimum: 0
                            maximum: 9007199254740991
                          sent:
                            type: integer
                            minimum: 0
                            maximum: 9007199254740991
                          replied:
                            type: integer
                            minimum: 0
                            maximum: 9007199254740991
                          bounced:
                            type: integer
                            minimum: 0
                            maximum: 9007199254740991
                          completed:
                            type: integer
                            minimum: 0
                            maximum: 9007199254740991
                          timed_out:
                            type: integer
                            minimum: 0
                            maximum: 9007199254740991
                          connection_sent:
                            type: integer
                            minimum: 0
                            maximum: 9007199254740991
                          connected:
                            type: integer
                            minimum: 0
                            maximum: 9007199254740991
                          connections_accepted:
                            type: integer
                            minimum: 0
                            maximum: 9007199254740991
                          message_sent:
                            type: integer
                            minimum: 0
                            maximum: 9007199254740991
                          contacted:
                            type: integer
                            minimum: 0
                            maximum: 9007199254740991
                        additionalProperties: false
                        nullable: true
                      created_at:
                        type: string
                        format: date-time
                      updated_at:
                        type: string
                        format: date-time
                      sequence_nodes:
                        type: array
                        items:
                          type: object
                          properties:
                            id:
                              type: string
                              format: uuid
                            campaign_id:
                              type: string
                              format: uuid
                            position:
                              type: integer
                              minimum: 0
                              maximum: 9007199254740991
                            type:
                              type: string
                              enum:
                                - connection_request
                                - email
                                - end
                            subject:
                              type: string
                              nullable: true
                            body:
                              type: string
                              nullable: true
                          required:
                            - id
                            - campaign_id
                            - position
                            - type
                          additionalProperties: false
                    required:
                      - id
                      - user_id
                      - type
                      - name
                      - status
                      - daily_limit
                      - stop_on_reply
                      - open_tracking
                      - signature
                      - skip_other_campaigns
                      - operating_hours
                      - stats
                      - created_at
                      - updated_at
                      - sequence_nodes
                    additionalProperties: false
                required:
                  - campaign
                additionalProperties: false
        '400':
          description: Validation failure for Outbound creation fields.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                required:
                  - error
                additionalProperties: false
        '401':
          description: Missing or invalid authentication.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                required:
                  - error
                additionalProperties: false
        '409':
          description: An Outbound execution with this name already exists.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                required:
                  - error
                additionalProperties: false
        '500':
          description: Outbound creation failed.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                required:
                  - error
                additionalProperties: false
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: pk_live_...

````