openapi: 3.1.0
info:
  title: Mumara ONE REST API V1 (Legacy)
  description: |
    The original Mumara ONE REST API. For new work use the [V2 API](../v2/); use V1 for the operations V2 doesn't cover yet:

    | To | Use |
    |----|-----|
    | Schedule a broadcast to send | `POST /broadcastSchedule` |
    | Import contacts from a file | `POST /importContacts` |
    | Create a trigger | `POST /addTrigger` |
    | Create a drip campaign | `POST /addDrip` |
    | Read your activity logs | `GET /getActivityLogs` |

    To **send transactional email**, use a Bridge and the [Sending API](../sending/) instead.

    ## Base URL
    ```
    https://one.mumara.com/api
    ```
    Leave off the trailing slash when you call the base URL itself (`/api`, which verifies your key): `/api/` is redirected, and a redirected `POST` can lose its body.

    ## Authentication
    Create an API key under **Setup → API Keys** in Mumara ONE, and choose the permissions it needs. Pass the key in one of three ways:

    **1. Bearer Token Header (recommended)**
    ```
    Authorization: Bearer YOUR_API_KEY
    ```

    **2. Query Parameter**
    ```
    GET /api/getLists?api_token=YOUR_API_KEY
    ```

    **3. Request Body**
    ```json
    {
      "api_token": "YOUR_API_KEY",
      "name": "My List"
    }
    ```

    The header keeps the key out of URLs and server logs, so prefer it. If your server strips the `Authorization` header, use `api_token`.

    | HTTP Status | Body | Cause |
    |------------|------|-------|
    | `401` | `{"status": "error", "result": "Error: Invalid or missing API token.", "suggestion": "..."}` | The key is missing or wrong |
    | `401` | `{"status": "error", "result": "This IP address is not authorized for access."}` | The key doesn't allow this IP address |
    | `403` | `{"status": "error", "result": "Error: API token has expired."}` | The key is switched off |
    | `403` | `{"status": "error", "result": "Error: Access Denied."}` | The key doesn't have permission for this operation |

    ## Rate Limiting
    Each key may make as many requests per minute as its **Rate limit**, set on the key under **Setup → API Keys**. Default: 60 requests/minute.

    Response headers include:
    - `X-RateLimit-Limit`: Maximum requests per minute
    - `X-RateLimit-Remaining`: Remaining requests in current window
    - `X-RateLimit-Reset`: Unix timestamp when the rate limit resets (when rate limited, HTTP 429)
    - `Retry-After`: Seconds to wait (when rate limited, HTTP 429)

    ## Pagination
    List endpoints support pagination with the following parameters:
    - `limit_start`: Offset (number of records to skip). Default: 0
    - `limit_count`: Number of records to return. Default: 25

    ## Response Format
    All responses are in JSON format.

    **Success Response:**
    ```json
    {
      "status": "success",
      "result": "Operation completed successfully",
      "response": { /* optional data object */ }
    }
    ```

    **Error Response:**
    ```json
    {
      "status": "error",
      "result": "Error message or validation errors object"
    }
    ```

    Some errors are returned with HTTP `200`, so always check `status`.

  version: 1.0.0
  contact:
    name: Mumara Support
    url: https://support.mumara.com
    email: support@mumara.com
  license:
    name: Proprietary
    url: https://mumara.com/terms

servers:
  - url: https://one.mumara.com/api
    description: Mumara ONE

tags:
  - name: Authentication
    description: Check that your API key works
  - name: Lists
    description: Manage contact lists and list groups
  - name: Contacts
    description: Manage subscribers/contacts
  - name: Broadcasts
    description: Email campaigns and broadcasts, and scheduling them to send
  - name: Statistics
    description: Campaign statistics and analytics
  - name: Pools
    description: |
      The sending routes of your Dedicated Pools. Mumara ONE creates and runs them; read them here to find the ids that `POST /broadcastSchedule` takes in `smtp_ids`.
  - name: Sending Domains
    description: |
      Read your sending domains. To add, verify and manage them, use the Sending Domains endpoints of the [V2 API](../v2/), which also apply your plan's rules and set the domain up on Mumara ONE's sending servers.
  - name: Suppression
    description: Email and domain suppression lists
  - name: Custom Fields
    description: Custom contact fields
  - name: Spin Tags
    description: Dynamic content spin tags
  - name: Segments
    description: Contact segmentation
  - name: Groups
    description: Groups for organizing lists, broadcasts, etc.
  - name: Automation
    description: Drips, triggers, and autoresponders
  - name: Web Forms
    description: Subscription forms

security:
  - apiKeyQuery: []
  - apiKeyBody: []
  - bearerAuth: []

paths:
  # ============================================
  # AUTHENTICATION
  # ============================================
  /:
    get:
      summary: Verify Authentication
      description: Verify that your API credentials are valid
      operationId: verifyAuth
      tags:
        - Authentication
      parameters:
        - $ref: '#/components/parameters/ApiToken'
      responses:
        '200':
          description: Authentication successful
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AuthResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
    post:
      summary: Verify Authentication (POST)
      description: Verify that your API credentials are valid via POST
      operationId: verifyAuthPost
      tags:
        - Authentication
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                api_token:
                  type: string
                  description: Your API token
              required:
                - api_token
      responses:
        '200':
          description: Authentication successful
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AuthResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'

  # ============================================
  # LISTS
  # ============================================
  /addList:
    post:
      summary: Create List
      description: |
        Create a new contact list. The domain of `owner_email` must be one of your verified sending domains. Mumara ONE handles bounces for you, so lists need no bounce address.
      operationId: addList
      tags:
        - Lists
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ListCreate'
            example:
              api_token: "your_api_token"
              list_name: "My Newsletter"
              owner_name: "John Doe"
              owner_email: "john@yourdomain.com"
              reply_email: "reply@yourdomain.com"
              group_name: "Marketing Lists"
              additional_fields: "first_name,last_name"
              response: "1"
      responses:
        '200':
          description: List created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListResponse'
              example:
                status: success
                result: "List has been created."
                response:
                  id: 1
                  name: "My Newsletter"
                  owner_name: "John Doe"
                  owner_email: "john@yourdomain.com"
                  reply_email: "reply@yourdomain.com"
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'

  /getLists:
    get:
      summary: Get All Lists
      description: Retrieve all contact lists with optional filtering
      operationId: getLists
      tags:
        - Lists
      parameters:
        - $ref: '#/components/parameters/ApiToken'
        - name: list_id
          in: query
          schema:
            type: integer
          description: Filter by specific list ID
        - name: group_id
          in: query
          schema:
            type: integer
          description: Filter by group ID
        - $ref: '#/components/parameters/LimitStart'
        - $ref: '#/components/parameters/LimitCount'
      responses:
        '200':
          description: Lists retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListsResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          description: No lists found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /getList/{id}:
    get:
      summary: Get List
      description: Retrieve a specific list by ID
      operationId: getList
      tags:
        - Lists
      parameters:
        - $ref: '#/components/parameters/ApiToken'
        - name: id
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: List retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListResponse'
        '404':
          $ref: '#/components/responses/NotFound'

  /updateList/{id}:
    put:
      summary: Update List
      description: Update an existing list
      operationId: updateList
      tags:
        - Lists
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ListUpdate'
      responses:
        '200':
          description: List updated successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListResponse'
        '404':
          $ref: '#/components/responses/NotFound'

  /deleteList/{id}/{type}:
    delete:
      summary: Delete List
      description: |
        Delete a list. The list cannot be deleted if it's being used by triggers or segments.
        Currently only 'hard' delete is supported (deletes subscribers).
      operationId: deleteList
      tags:
        - Lists
      parameters:
        - $ref: '#/components/parameters/ApiToken'
        - name: id
          in: path
          required: true
          schema:
            type: integer
        - name: type
          in: path
          required: false
          schema:
            type: string
            enum: [hard]
            default: hard
          description: Delete type (currently only 'hard' is supported)
      responses:
        '200':
          description: List deleted successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          description: List is in use by triggers or segments
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /getListGroups:
    get:
      summary: Get List Groups
      description: Retrieve all list groups with the count of lists in each group
      operationId: getListGroups
      tags:
        - Lists
      parameters:
        - $ref: '#/components/parameters/ApiToken'
        - name: id
          in: query
          schema:
            type: integer
          description: Filter by specific group ID
        - $ref: '#/components/parameters/LimitStart'
        - $ref: '#/components/parameters/LimitCount'
      responses:
        '200':
          description: List groups retrieved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  result:
                    type: array
                    items:
                      $ref: '#/components/schemas/ListGroup'

  /deleteListGroup/{id}/{delete_lists}:
    delete:
      summary: Delete List Group
      description: |
        Delete a list group. Options:
        - If `delete_lists=1`: Delete all lists in the group (fails if any list is used by triggers/segments)
        - If `delete_lists=0` or omitted: Move lists to "Unsorted" group
      operationId: deleteListGroup
      tags:
        - Lists
      parameters:
        - $ref: '#/components/parameters/ApiToken'
        - name: id
          in: path
          required: true
          schema:
            type: integer
          description: Group ID to delete
        - name: delete_lists
          in: path
          required: false
          schema:
            type: integer
            enum: [0, 1]
            default: 0
          description: Whether to delete lists (1) or move to Unsorted (0)
      responses:
        '200':
          description: Group deleted successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
        '404':
          description: Group not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  # ============================================
  # CONTACTS/SUBSCRIBERS
  # ============================================
  /addContact:
    post:
      summary: Add Contact
      description: Add a new contact to a list
      operationId: addContact
      tags:
        - Contacts
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ContactCreate'
      responses:
        '200':
          description: Contact added successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ContactResponse'
        '400':
          $ref: '#/components/responses/BadRequest'

  /getContacts:
    get:
      summary: Get All Contacts
      description: Retrieve contacts with optional filtering
      operationId: getContacts
      tags:
        - Contacts
      parameters:
        - $ref: '#/components/parameters/ApiToken'
        - name: list_id
          in: query
          schema:
            type: integer
          description: Filter by list ID
        - name: status
          in: query
          schema:
            type: string
            enum: [subscribed, unsubscribed, bounced, complaint]
        - $ref: '#/components/parameters/LimitStart'
        - $ref: '#/components/parameters/LimitCount'
      responses:
        '200':
          description: Contacts retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ContactsResponse'

  /getContact/{ids}:
    get:
      summary: Get Contact(s)
      description: Retrieve one or more contacts by ID
      operationId: getContact
      tags:
        - Contacts
      parameters:
        - $ref: '#/components/parameters/ApiToken'
        - name: ids
          in: path
          required: true
          schema:
            type: string
          description: Single ID or comma-separated IDs
      responses:
        '200':
          description: Contact(s) retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ContactResponse'
        '404':
          $ref: '#/components/responses/NotFound'

  /searchContacts:
    get:
      summary: Search Contacts
      description: Search contacts by various criteria
      operationId: searchContacts
      tags:
        - Contacts
      parameters:
        - $ref: '#/components/parameters/ApiToken'
        - name: q
          in: query
          required: true
          schema:
            type: string
          description: Search query (email, name, etc.)
        - name: list_id
          in: query
          schema:
            type: integer
        - name: field
          in: query
          schema:
            type: string
          description: Specific field to search
        - $ref: '#/components/parameters/LimitStart'
        - $ref: '#/components/parameters/LimitCount'
      responses:
        '200':
          description: Search results
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ContactsResponse'

  /updateContact/{id}:
    put:
      summary: Update Contact
      description: Update contact information by ID
      operationId: updateContact
      tags:
        - Contacts
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ContactUpdate'
      responses:
        '200':
          description: Contact updated successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ContactResponse'

  /updateContactByEmail/{email}:
    put:
      summary: Update Contact by Email
      description: Update contact using email address
      operationId: updateContactByEmail
      tags:
        - Contacts
      parameters:
        - name: email
          in: path
          required: true
          schema:
            type: string
            format: email
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ContactUpdate'
      responses:
        '200':
          description: Contact updated successfully

  /deleteContact/{ids}:
    delete:
      summary: Delete Contact(s)
      description: Delete one or more contacts by ID
      operationId: deleteContact
      tags:
        - Contacts
      parameters:
        - $ref: '#/components/parameters/ApiToken'
        - name: ids
          in: path
          required: true
          schema:
            type: string
          description: Single ID or comma-separated IDs
      responses:
        '200':
          description: Contact(s) deleted successfully

  /deleteContactByEmail/{email}/{recursive}/{list_id}:
    delete:
      summary: Delete Contact by Email
      description: Delete contact using email address
      operationId: deleteContactByEmail
      tags:
        - Contacts
      parameters:
        - $ref: '#/components/parameters/ApiToken'
        - name: email
          in: path
          required: true
          schema:
            type: string
            format: email
        - name: recursive
          in: path
          required: false
          schema:
            type: integer
            enum: [0, 1]
            default: 0
          description: Delete from all lists (1) or specific list (0)
        - name: list_id
          in: path
          required: false
          schema:
            type: integer
          description: Specific list to delete from (when recursive=0)
      responses:
        '200':
          description: Contact deleted successfully

  /markAsBounced/{id}:
    put:
      summary: Mark as Bounced
      description: Mark a contact as bounced
      operationId: markAsBounced
      tags:
        - Contacts
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                api_token:
                  type: string
      responses:
        '200':
          description: Contact marked as bounced

  /markAsUnsubscribed/{id}:
    put:
      summary: Mark as Unsubscribed
      description: Mark a contact as unsubscribed
      operationId: markAsUnsubscribed
      tags:
        - Contacts
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                api_token:
                  type: string
      responses:
        '200':
          description: Contact marked as unsubscribed

  /markAsComplaint/{id}:
    put:
      summary: Mark as Complaint
      description: Mark a contact as complaint/spam report
      operationId: markAsComplaint
      tags:
        - Contacts
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                api_token:
                  type: string
      responses:
        '200':
          description: Contact marked as complaint

  /importContacts:
    post:
      summary: Import Contacts
      description: Bulk import contacts to a list
      operationId: importContacts
      tags:
        - Contacts
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ContactImport'
      responses:
        '200':
          description: Import started successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                  imported:
                    type: integer
                  failed:
                    type: integer
                  message:
                    type: string

  # ============================================
  # SEGMENTS
  # ============================================
  /createSegment:
    post:
      summary: Create Segment
      description: Create a new contact segment with conditions
      operationId: createSegment
      tags:
        - Segments
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SegmentCreate'
            example:
              api_token: "your_api_token"
              name: "Active Subscribers"
              list_ids: "1,2,3"
              conditions:
                - field: "status"
                  operator: "equals"
                  value: "subscribed"
      responses:
        '200':
          description: Segment created successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  result:
                    type: string

  # ============================================
  # BROADCASTS/CAMPAIGNS
  # ============================================
  /addBroadcast:
    post:
      summary: Create Broadcast
      description: Create a new email broadcast/campaign
      operationId: addBroadcast
      tags:
        - Broadcasts
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BroadcastCreate'
      responses:
        '200':
          description: Broadcast created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BroadcastResponse'

  /getBroadcasts:
    get:
      summary: Get All Broadcasts
      description: Retrieve all broadcasts/campaigns
      operationId: getBroadcasts
      tags:
        - Broadcasts
      parameters:
        - $ref: '#/components/parameters/ApiToken'
        - name: status
          in: query
          schema:
            type: string
            enum: [draft, scheduled, sending, sent, paused]
        - $ref: '#/components/parameters/LimitStart'
        - $ref: '#/components/parameters/LimitCount'
      responses:
        '200':
          description: Broadcasts retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BroadcastsResponse'

  /getBroadcast/{id}:
    get:
      summary: Get Broadcast
      description: Retrieve a specific broadcast by ID
      operationId: getBroadcast
      tags:
        - Broadcasts
      parameters:
        - $ref: '#/components/parameters/ApiToken'
        - name: id
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Broadcast retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BroadcastResponse'
        '404':
          $ref: '#/components/responses/NotFound'

  /updateBroadcast/{id}:
    put:
      summary: Update Broadcast
      description: Update an existing broadcast
      operationId: updateBroadcast
      tags:
        - Broadcasts
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BroadcastUpdate'
      responses:
        '200':
          description: Broadcast updated successfully

  /deleteBroadcasts/{id}:
    delete:
      summary: Delete Broadcast
      description: Delete a broadcast
      operationId: deleteBroadcast
      tags:
        - Broadcasts
      parameters:
        - $ref: '#/components/parameters/ApiToken'
        - name: id
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Broadcast deleted successfully

  /broadcastSchedule:
    post:
      summary: Schedule Broadcast
      description: |
        Schedule one or more broadcasts to send to lists or segments, now or later. This is the API equivalent of **Campaigns → Schedule** in the app.

        Before scheduling, find:
        - the broadcast ids (`GET /getBroadcasts`, or V2 `GET /broadcasts`);
        - the list or segment ids;
        - the id of the pool to send through (`GET /getSendingNodes`), for `smtp_ids`.

        The schedule is charged against your sending allowance when it sends, as from the app. Errors are returned with `"status": "error"` and the problem in `result`, which for invalid fields is an object of messages by field name, for example `{"smtp_ids": ["Active Nodes with provided smtp ids do not exist"]}`.
      operationId: scheduleBroadcast
      tags:
        - Broadcasts
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BroadcastSchedule'
      responses:
        '200':
          description: 'Broadcast scheduled successfully, or an error with `"status": "error"`'
          content:
            application/json:
              examples:
                scheduled:
                  summary: Scheduled
                  value:
                    status: success
                    result: 'Success: Campaign has been scheduled successfully.'
                invalid:
                  summary: A field is invalid
                  value:
                    status: error
                    result:
                      sending_pattern:
                        - The selected sending pattern is invalid.

  /getScheduledBroadcasts:
    get:
      summary: Get Scheduled Broadcasts
      description: Retrieve all scheduled broadcasts
      operationId: getScheduledBroadcasts
      tags:
        - Broadcasts
      parameters:
        - $ref: '#/components/parameters/ApiToken'
        - $ref: '#/components/parameters/LimitStart'
        - $ref: '#/components/parameters/LimitCount'
      responses:
        '200':
          description: Scheduled broadcasts retrieved

  /getBroadcastGroups:
    get:
      summary: Get Broadcast Groups
      description: Retrieve broadcast groups with campaign count
      operationId: getBroadcastGroups
      tags:
        - Broadcasts
      parameters:
        - $ref: '#/components/parameters/ApiToken'
        - name: id
          in: query
          schema:
            type: integer
          description: Filter by specific group ID
        - $ref: '#/components/parameters/LimitStart'
        - $ref: '#/components/parameters/LimitCount'
      responses:
        '200':
          description: Broadcast groups retrieved
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                  result:
                    type: array
                    items:
                      $ref: '#/components/schemas/BroadcastGroup'

  # ============================================
  # GROUPS (Generic)
  # ============================================
  /getGroups/{module}:
    get:
      summary: Get Groups by Module
      description: |
        Retrieve groups for a specific module type.

        Supported modules:
        - `list` - List groups
        - `broadcast` - Broadcast/campaign groups
        - `customField` - Custom field groups
      operationId: getGroups
      tags:
        - Groups
      parameters:
        - $ref: '#/components/parameters/ApiToken'
        - name: module
          in: path
          required: true
          schema:
            type: string
            enum: [list, broadcast, customField]
          description: Module type
        - name: id
          in: query
          schema:
            type: integer
          description: Filter by specific group ID
        - name: module_id
          in: query
          schema:
            type: integer
          description: Filter by specific module item ID
        - $ref: '#/components/parameters/LimitStart'
        - $ref: '#/components/parameters/LimitCount'
      responses:
        '200':
          description: Groups retrieved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  result:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: integer
                        name:
                          type: string
                        module_name:
                          type: string
                          description: Comma-separated names of items in this group
                        created_at:
                          type: string
                          format: date-time
                        updated_at:
                          type: string
                          format: date-time
        '400':
          description: Invalid module name
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: error
                  result:
                    type: string
                  suggested module name:
                    type: array
                    items:
                      type: string
                    example: ["list", "customField", "broadcast"]

  # ============================================
  # STATISTICS
  # ============================================
  /getBroadcastStatsSummary/{schedule_id}:
    get:
      summary: Get Stats Summary
      description: Get summary statistics for a broadcast schedule
      operationId: getStatsSummary
      tags:
        - Statistics
      parameters:
        - $ref: '#/components/parameters/ApiToken'
        - name: schedule_id
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Statistics summary
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StatsSummary'

  /getBroadcastStatsBounced/{schedule_id}:
    get:
      summary: Get Bounce Stats
      description: Get bounce statistics for a broadcast
      operationId: getStatsBounced
      tags:
        - Statistics
      parameters:
        - $ref: '#/components/parameters/ApiToken'
        - name: schedule_id
          in: path
          required: true
          schema:
            type: integer
        - $ref: '#/components/parameters/LimitStart'
        - $ref: '#/components/parameters/LimitCount'
      responses:
        '200':
          description: Bounce statistics
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StatsDetail'

  /getBroadcastStatsOpened/{schedule_id}:
    get:
      summary: Get Open Stats
      description: Get open statistics for a broadcast
      operationId: getStatsOpened
      tags:
        - Statistics
      parameters:
        - $ref: '#/components/parameters/ApiToken'
        - name: schedule_id
          in: path
          required: true
          schema:
            type: integer
        - $ref: '#/components/parameters/LimitStart'
        - $ref: '#/components/parameters/LimitCount'
      responses:
        '200':
          description: Open statistics

  /getBroadcastStatsClicked/{schedule_id}:
    get:
      summary: Get Click Stats
      description: Get click statistics for a broadcast
      operationId: getStatsClicked
      tags:
        - Statistics
      parameters:
        - $ref: '#/components/parameters/ApiToken'
        - name: schedule_id
          in: path
          required: true
          schema:
            type: integer
        - $ref: '#/components/parameters/LimitStart'
        - $ref: '#/components/parameters/LimitCount'
      responses:
        '200':
          description: Click statistics

  /getBroadcastStatsUnsubscribed/{schedule_id}:
    get:
      summary: Get Unsubscribe Stats
      description: Get unsubscribe statistics for a broadcast
      operationId: getStatsUnsubscribed
      tags:
        - Statistics
      parameters:
        - $ref: '#/components/parameters/ApiToken'
        - name: schedule_id
          in: path
          required: true
          schema:
            type: integer
        - $ref: '#/components/parameters/LimitStart'
        - $ref: '#/components/parameters/LimitCount'
      responses:
        '200':
          description: Unsubscribe statistics

  /getBroadcastStatsComplaints/{schedule_id}:
    get:
      summary: Get Complaint Stats
      description: Get complaint/spam report statistics
      operationId: getStatsComplaints
      tags:
        - Statistics
      parameters:
        - $ref: '#/components/parameters/ApiToken'
        - name: schedule_id
          in: path
          required: true
          schema:
            type: integer
        - $ref: '#/components/parameters/LimitStart'
        - $ref: '#/components/parameters/LimitCount'
      responses:
        '200':
          description: Complaint statistics

  /getBroadcastStatsLogs/{schedule_id}:
    get:
      summary: Get Stats Logs
      description: Get detailed sending logs for a broadcast
      operationId: getStatsLogs
      tags:
        - Statistics
      parameters:
        - $ref: '#/components/parameters/ApiToken'
        - name: schedule_id
          in: path
          required: true
          schema:
            type: integer
        - $ref: '#/components/parameters/LimitStart'
        - $ref: '#/components/parameters/LimitCount'
      responses:
        '200':
          description: Sending logs

  /getBroadcastStatsGlobal:
    get:
      summary: Get Global Stats
      description: Get global statistics across all broadcasts
      operationId: getGlobalStats
      tags:
        - Statistics
      parameters:
        - $ref: '#/components/parameters/ApiToken'
        - name: start_date
          in: query
          schema:
            type: string
            format: date
        - name: end_date
          in: query
          schema:
            type: string
            format: date
      responses:
        '200':
          description: Global statistics

  /getLogsByIds/{ids}:
    get:
      summary: Get Logs by IDs
      description: Retrieve campaign schedule logs by their IDs
      operationId: getLogsByIds
      tags:
        - Statistics
      parameters:
        - $ref: '#/components/parameters/ApiToken'
        - name: ids
          in: path
          required: true
          schema:
            type: string
          description: Single ID or comma-separated IDs
      responses:
        '200':
          description: Logs retrieved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  result:
                    type: array
                    items:
                      type: object
        '404':
          description: Logs not found

  # ============================================
  # SPIN TAGS
  # ============================================
  /getSpinTags:
    get:
      summary: Get Spin Tags
      description: Retrieve all spin tags for dynamic content rotation
      operationId: getSpinTags
      tags:
        - Spin Tags
      parameters:
        - $ref: '#/components/parameters/ApiToken'
        - name: id
          in: query
          schema:
            type: integer
          description: Filter by specific spin tag ID
        - $ref: '#/components/parameters/LimitStart'
        - $ref: '#/components/parameters/LimitCount'
      responses:
        '200':
          description: Spin tags retrieved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  result:
                    type: array
                    items:
                      $ref: '#/components/schemas/SpinTag'

  /addSpinTag:
    post:
      summary: Add Spin Tag
      description: Create a new spin tag for dynamic content
      operationId: addSpinTag
      tags:
        - Spin Tags
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SpinTagCreate'
            example:
              api_token: "your_api_token"
              place_holder: "greeting"
              word_list: "Hello,Hi,Hey,Greetings"
              response: "1"
      responses:
        '200':
          description: Spin tag created successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  result:
                    type: string
                    example: "Spintag has been added."
                  response:
                    $ref: '#/components/schemas/SpinTag'
        '400':
          description: Validation error or spin tag already exists

  /updateSpinTag/{id}:
    put:
      summary: Update Spin Tag
      description: Update an existing spin tag's word list
      operationId: updateSpinTag
      tags:
        - Spin Tags
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SpinTagUpdate'
      responses:
        '200':
          description: Spin tag updated successfully
        '404':
          description: Spin tag not found

  /deleteSpinTags/{ids}:
    delete:
      summary: Delete Spin Tags
      description: Delete one or more spin tags
      operationId: deleteSpinTags
      tags:
        - Spin Tags
      parameters:
        - $ref: '#/components/parameters/ApiToken'
        - name: ids
          in: path
          required: true
          schema:
            type: string
          description: Single ID or comma-separated IDs
      responses:
        '200':
          description: Spin tag(s) deleted successfully

  /getSendingNodes:
    get:
      summary: Get Your Pools
      description: List the sending routes of your Dedicated Pools. Use their `id` values in `smtp_ids` when you schedule a broadcast.
      operationId: getSendingNodes
      tags:
        - Pools
      parameters:
        - $ref: '#/components/parameters/ApiToken'
        - $ref: '#/components/parameters/LimitStart'
        - $ref: '#/components/parameters/LimitCount'
      responses:
        '200':
          description: Pools retrieved
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                  result:
                    type: array
                    items:
                      $ref: '#/components/schemas/SendingNode'

  /getSendingNode/{id}:
    get:
      summary: Get a Pool
      description: Retrieve one sending route of your Dedicated Pools by its id.
      operationId: getSendingNode
      tags:
        - Pools
      parameters:
        - $ref: '#/components/parameters/ApiToken'
        - name: id
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Pool retrieved

  # ============================================
  # SENDING DOMAINS
  # ============================================
  /getSendingDomains:
    get:
      summary: Get Sending Domains
      description: Retrieve all sending domains
      operationId: getSendingDomains
      tags:
        - Sending Domains
      parameters:
        - $ref: '#/components/parameters/ApiToken'
      responses:
        '200':
          description: Sending domains retrieved

  # ============================================
  # SUPPRESSION
  # ============================================
  /suppress:
    post:
      summary: Add to Suppression List
      description: Add email or domain to suppression list
      operationId: suppress
      tags:
        - Suppression
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SuppressionAdd'
      responses:
        '200':
          description: Added to suppression list

  /getSuppressed:
    get:
      summary: Get Suppressed
      description: Get suppressed emails and domains
      operationId: getSuppressed
      tags:
        - Suppression
      parameters:
        - $ref: '#/components/parameters/ApiToken'
      responses:
        '200':
          description: Suppression list retrieved

  /getSuppressedEmails/{id}:
    get:
      summary: Get Suppressed Emails
      description: Get suppressed email addresses
      operationId: getSuppressedEmails
      tags:
        - Suppression
      parameters:
        - $ref: '#/components/parameters/ApiToken'
        - name: id
          in: path
          required: false
          schema:
            type: integer
      responses:
        '200':
          description: Suppressed emails retrieved

  /getSuppressedDomains/{id}:
    get:
      summary: Get Suppressed Domains
      description: Get suppressed domains
      operationId: getSuppressedDomains
      tags:
        - Suppression
      parameters:
        - $ref: '#/components/parameters/ApiToken'
        - name: id
          in: path
          required: false
          schema:
            type: integer
      responses:
        '200':
          description: Suppressed domains retrieved

  /deleteSuppressed/{type}:
    delete:
      summary: Delete Suppressed
      description: Remove from suppression list
      operationId: deleteSuppressed
      tags:
        - Suppression
      parameters:
        - $ref: '#/components/parameters/ApiToken'
        - name: type
          in: path
          required: true
          schema:
            type: string
            enum: [email, domain]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                api_token:
                  type: string
                ids:
                  type: array
                  items:
                    type: integer
      responses:
        '200':
          description: Removed from suppression list

  # ============================================
  # CUSTOM FIELDS
  # ============================================
  /getCustomFields:
    get:
      summary: Get Custom Fields
      description: Retrieve all custom fields
      operationId: getCustomFields
      tags:
        - Custom Fields
      parameters:
        - $ref: '#/components/parameters/ApiToken'
      responses:
        '200':
          description: Custom fields retrieved

  /getCustomField/{id}:
    get:
      summary: Get Custom Field
      description: Retrieve a specific custom field
      operationId: getCustomField
      tags:
        - Custom Fields
      parameters:
        - $ref: '#/components/parameters/ApiToken'
        - name: id
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Custom field retrieved

  /getListCustomFields/{list_id}:
    get:
      summary: Get List Custom Fields
      description: Get custom fields assigned to a specific list
      operationId: getListCustomFields
      tags:
        - Custom Fields
      parameters:
        - $ref: '#/components/parameters/ApiToken'
        - name: list_id
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: List custom fields retrieved

  /addCustomField:
    post:
      summary: Add Custom Field
      description: Create a new custom field
      operationId: addCustomField
      tags:
        - Custom Fields
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CustomField'
      responses:
        '200':
          description: Custom field created

  /addCustomFieldToList:
    post:
      summary: Add Custom Field to List
      description: Assign a custom field to a list
      operationId: addCustomFieldToList
      tags:
        - Custom Fields
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                api_token:
                  type: string
                list_id:
                  type: integer
                field_id:
                  type: integer
      responses:
        '200':
          description: Custom field added to list

  /updateCustomField/{id}:
    put:
      summary: Update Custom Field
      description: Update a custom field
      operationId: updateCustomField
      tags:
        - Custom Fields
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CustomField'
      responses:
        '200':
          description: Custom field updated

  /deleteCustomField/{id}/{force}:
    delete:
      summary: Delete Custom Field
      description: Delete a custom field
      operationId: deleteCustomField
      tags:
        - Custom Fields
      parameters:
        - $ref: '#/components/parameters/ApiToken'
        - name: id
          in: path
          required: true
          schema:
            type: integer
        - name: force
          in: path
          required: false
          schema:
            type: integer
            enum: [0, 1]
      responses:
        '200':
          description: Custom field deleted

  # ============================================
  # AUTOMATION - DRIPS
  # ============================================
  /getDrips:
    get:
      summary: Get Drips
      description: Retrieve all drip campaigns
      operationId: getDrips
      tags:
        - Automation
      parameters:
        - $ref: '#/components/parameters/ApiToken'
      responses:
        '200':
          description: Drips retrieved

  /addDrip:
    post:
      summary: Add Drip
      description: Create a new drip campaign
      operationId: addDrip
      tags:
        - Automation
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DripCreate'
      responses:
        '200':
          description: Drip created

  /deleteDrips/{ids}:
    delete:
      summary: Delete Drips
      description: Delete drip campaigns
      operationId: deleteDrips
      tags:
        - Automation
      parameters:
        - $ref: '#/components/parameters/ApiToken'
        - name: ids
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Drips deleted

  # ============================================
  # AUTOMATION - TRIGGERS
  # ============================================
  /getTriggers:
    get:
      summary: Get Triggers
      description: Retrieve all triggers
      operationId: getTriggers
      tags:
        - Automation
      parameters:
        - $ref: '#/components/parameters/ApiToken'
      responses:
        '200':
          description: Triggers retrieved

  /getTrigger/{id}:
    get:
      summary: Get Trigger
      description: Retrieve a specific trigger
      operationId: getTrigger
      tags:
        - Automation
      parameters:
        - $ref: '#/components/parameters/ApiToken'
        - name: id
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Trigger retrieved

  /addTrigger:
    post:
      summary: Add Trigger
      description: Create a new trigger
      operationId: addTrigger
      tags:
        - Automation
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TriggerCreate'
      responses:
        '200':
          description: Trigger created

  /deleteTriggers/{ids}:
    delete:
      summary: Delete Triggers
      description: Delete triggers
      operationId: deleteTriggers
      tags:
        - Automation
      parameters:
        - $ref: '#/components/parameters/ApiToken'
        - name: ids
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Triggers deleted

  # ============================================
  # WEB FORMS
  # ============================================
  /getWebForms:
    get:
      summary: Get Web Forms
      description: Retrieve all web forms
      operationId: getWebForms
      tags:
        - Web Forms
      parameters:
        - $ref: '#/components/parameters/ApiToken'
      responses:
        '200':
          description: Web forms retrieved

  /getWebForm/{id}:
    get:
      summary: Get Web Form
      description: Retrieve a specific web form
      operationId: getWebForm
      tags:
        - Web Forms
      parameters:
        - $ref: '#/components/parameters/ApiToken'
        - name: id
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Web form retrieved

  /deleteWebForms/{id}:
    delete:
      summary: Delete Web Forms
      description: Delete web forms
      operationId: deleteWebForms
      tags:
        - Web Forms
      parameters:
        - $ref: '#/components/parameters/ApiToken'
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Web forms deleted

  # ============================================
  # ACTIVITY LOGS
  # ============================================
  /getActivityLogs:
    get:
      summary: Get Activity Logs
      description: Retrieve activity logs
      operationId: getActivityLogs
      tags:
        - Statistics
      parameters:
        - $ref: '#/components/parameters/ApiToken'
        - $ref: '#/components/parameters/LimitStart'
        - $ref: '#/components/parameters/LimitCount'
        - name: type
          in: query
          schema:
            type: string
      responses:
        '200':
          description: Activity logs retrieved

# COMPONENTS
# ============================================
components:
  securitySchemes:
    apiKeyQuery:
      type: apiKey
      in: query
      name: api_token
      description: API token passed as query parameter
    apiKeyBody:
      type: apiKey
      in: header
      name: X-API-Token
      description: API token in request body (use api_token field)
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API Key
      description: Bearer token authentication

  parameters:
    ApiToken:
      name: api_token
      in: query
      required: false
      schema:
        type: string
      description: API token (can also be passed in request body)
    LimitStart:
      name: limit_start
      in: query
      schema:
        type: integer
        default: 0
      description: Pagination offset (number of records to skip)
    LimitCount:
      name: limit_count
      in: query
      schema:
        type: integer
        default: 25
      description: Number of records to return

  responses:
    Unauthorized:
      description: Authentication failed
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            status: error
            result: "Invalid API key"

    BadRequest:
      description: Invalid request
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ValidationErrorResponse'

    NotFound:
      description: Resource not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            status: error
            result: "Resource not found"

  schemas:
    # ============================================
    # EXISTING API SCHEMAS
    # ============================================
    SuccessResponse:
      type: object
      properties:
        status:
          type: string
          example: success
        result:
          type: string

    ErrorResponse:
      type: object
      properties:
        status:
          type: string
          example: error
        result:
          oneOf:
            - type: string
            - type: object

    ValidationErrorResponse:
      type: object
      properties:
        status:
          type: string
          example: error
        result:
          type: object
          additionalProperties:
            type: array
            items:
              type: string

    AuthResponse:
      type: object
      properties:
        status:
          type: string
          example: success
        message:
          type: string
          example: Authentication successful
        user:
          type: object
          properties:
            id:
              type: integer
            email:
              type: string
            name:
              type: string

    # LIST SCHEMAS
    ListCreate:
      type: object
      required:
        - list_name
        - owner_name
        - owner_email
        - reply_email
      properties:
        api_token:
          type: string
        list_name:
          type: string
          example: "My Newsletter"
        owner_name:
          type: string
          example: "John Doe"
        owner_email:
          type: string
          format: email
          description: Must use a verified sending domain
        bounce_email:
          type: string
          format: email
          description: Not needed in Mumara ONE, which processes bounces for you. Leave it out.
        reply_email:
          type: string
          format: email
        group_name:
          type: string
          description: Group name (will be created if doesn't exist)
        additional_fields:
          type: string
          description: Comma-separated custom field tags to assign
        additional_headers:
          type: string
          description: JSON object of additional email headers
        response:
          type: string
          enum: ["0", "1"]
          description: Set to "1" to include created list in response

    ListUpdate:
      type: object
      properties:
        api_token:
          type: string
        list_name:
          type: string
        owner_name:
          type: string
        owner_email:
          type: string
          format: email
        bounce_email:
          type: string
          format: email
        reply_email:
          type: string
          format: email
        group_name:
          type: string
        additional_fields:
          type: string
        additional_headers:
          type: string
        response:
          type: string
          enum: ["0", "1"]

    ListResponse:
      type: object
      properties:
        status:
          type: string
        result:
          oneOf:
            - type: string
            - type: array
              items:
                $ref: '#/components/schemas/List'
        response:
          $ref: '#/components/schemas/List'

    ListsResponse:
      type: object
      properties:
        status:
          type: string
        result:
          type: array
          items:
            $ref: '#/components/schemas/List'

    List:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        owner_name:
          type: string
        owner_email:
          type: string
        reply_email:
          type: string
        user_id:
          type: integer
        group_id:
          type: integer
        group_name:
          type: string
        total_subscribers:
          type: integer
        bounce_id:
          type: integer
        bounce_email:
          type: string
        custom_fields:
          type: object
          additionalProperties:
            type: string
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time

    ListGroup:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        user_id:
          type: integer
        number_of_lists_in_group:
          type: integer

    BroadcastGroup:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        user_id:
          type: integer
        number_of_campaigns_in_group:
          type: integer

    Group:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        type:
          type: string

    # CONTACT SCHEMAS
    ContactCreate:
      type: object
      required:
        - email
        - list_id
      properties:
        api_token:
          type: string
        email:
          type: string
          format: email
        list_id:
          type: integer
        first_name:
          type: string
        last_name:
          type: string
        phone:
          type: string
        custom_fields:
          type: object
          additionalProperties:
            type: string
        tags:
          type: array
          items:
            type: string
        status:
          type: string
          enum: [subscribed, unsubscribed]
          default: subscribed

    ContactUpdate:
      type: object
      properties:
        api_token:
          type: string
        email:
          type: string
          format: email
        first_name:
          type: string
        last_name:
          type: string
        phone:
          type: string
        custom_fields:
          type: object
          additionalProperties:
            type: string
        tags:
          type: array
          items:
            type: string
        status:
          type: string
          enum: [subscribed, unsubscribed]

    ContactResponse:
      type: object
      properties:
        status:
          type: string
        result:
          oneOf:
            - type: string
            - $ref: '#/components/schemas/Contact'
            - type: array
              items:
                $ref: '#/components/schemas/Contact'

    ContactsResponse:
      type: object
      properties:
        status:
          type: string
        result:
          type: array
          items:
            $ref: '#/components/schemas/Contact'

    Contact:
      type: object
      properties:
        id:
          type: integer
        email:
          type: string
        first_name:
          type: string
        last_name:
          type: string
        phone:
          type: string
        status:
          type: string
        list_id:
          type: integer
        custom_fields:
          type: object
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time

    ContactImport:
      type: object
      required:
        - list_id
        - contacts
      properties:
        api_token:
          type: string
        list_id:
          type: integer
        contacts:
          type: array
          items:
            type: object
            required:
              - email
            properties:
              email:
                type: string
                format: email
              first_name:
                type: string
              last_name:
                type: string
              custom_fields:
                type: object
        update_existing:
          type: boolean
          default: false
        skip_duplicates:
          type: boolean
          default: true

    # SEGMENT SCHEMAS
    SegmentCreate:
      type: object
      required:
        - name
        - list_ids
      properties:
        api_token:
          type: string
        name:
          type: string
        list_ids:
          type: string
          description: Comma-separated list IDs
        conditions:
          type: array
          items:
            type: object
            properties:
              field:
                type: string
              operator:
                type: string
              value:
                type: string

    # BROADCAST SCHEMAS
    BroadcastCreate:
      type: object
      required:
        - name
        - subject
        - from_name
        - from_email
      properties:
        api_token:
          type: string
        name:
          type: string
        subject:
          type: string
        from_name:
          type: string
        from_email:
          type: string
          format: email
        reply_to:
          type: string
          format: email
        html_content:
          type: string
        text_content:
          type: string
        template_id:
          type: integer
        list_ids:
          type: array
          items:
            type: integer
        segment_ids:
          type: array
          items:
            type: integer
        sending_node_id:
          type: integer
        group_id:
          type: integer

    BroadcastUpdate:
      type: object
      properties:
        api_token:
          type: string
        name:
          type: string
        subject:
          type: string
        from_name:
          type: string
        from_email:
          type: string
          format: email
        reply_to:
          type: string
          format: email
        html_content:
          type: string
        text_content:
          type: string

    BroadcastResponse:
      type: object
      properties:
        status:
          type: string
        result:
          oneOf:
            - type: string
            - $ref: '#/components/schemas/Broadcast'

    BroadcastsResponse:
      type: object
      properties:
        status:
          type: string
        result:
          type: array
          items:
            $ref: '#/components/schemas/Broadcast'

    Broadcast:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        subject:
          type: string
        from_name:
          type: string
        from_email:
          type: string
        status:
          type: string
        created_at:
          type: string
          format: date-time

    BroadcastSchedule:
      type: object
      required:
        - name
        - type
        - broadcast_ids
        - smtp_ids
        - smtp_sequence
        - sending_pattern
        - sending_time
        - sender_type
      properties:
        api_token:
          type: string
        name:
          type: string
          description: A name for this schedule, shown in **Campaigns → Schedule** and in statistics.
          example: October newsletter
        type:
          type: string
          enum: [subscriber, segment]
          description: Send to lists (`subscriber`, with `list_ids`) or to segments (`segment`, with `segment_ids`).
        list_ids:
          type: string
          description: Comma-separated list ids. Required when `type` is `subscriber`.
          example: '12,15'
        segment_ids:
          type: string
          description: Comma-separated segment ids. Required when `type` is `segment`.
          example: '4'
        broadcast_ids:
          type: string
          description: Comma-separated ids of the broadcasts to send. With several, each contact gets one of them, chosen by `sending_pattern`.
          example: '31'
        smtp_ids:
          type: string
          description: Comma-separated ids of the pools to send through, from `GET /getSendingNodes`. At least one must be an active pool of your account; ids that aren't are left out.
          example: '7'
        smtp_sequence:
          type: string
          enum: [batch, loop]
          description: How the sending moves between several pools in `smtp_ids`.
        sending_pattern:
          type: string
          enum: [random, sequential]
          description: How the broadcasts in `broadcast_ids` are picked for each contact.
        sending_time:
          type: string
          enum: [now, later]
          description: Send straight away, or at `send_datetime`.
        send_datetime:
          type: string
          description: When to send, as `YYYY-MM-DD HH:MM:SS` in your account's time zone. Required when `sending_time` is `later`, and must be in the future.
          example: '2026-10-20 09:00:00'
        sender_type:
          type: string
          enum: [list, custom, smtp]
          description: |
            Where the From details come from:
            - `list` (recommended): each list's owner name, owner email and reply address.
            - `custom`: `from_name`, `from_email`, `reply_email` and `bounce_email` below.
            - `smtp`: the pool's own sender details.
        from_name:
          type: string
          description: Required when `sender_type` is `custom`.
        from_email:
          type: string
          format: email
          description: Required when `sender_type` is `custom`. Its domain must be one of your verified sending domains.
        reply_email:
          type: string
          format: email
          description: Required when `sender_type` is `custom`.
        bounce_email:
          type: string
          format: email
          description: Required when `sender_type` is `custom`, and must be a bounce address of your account. Mumara ONE manages bounces for you, so use `sender_type` `list` unless Mumara ONE support has given you one.
        track_opens:
          type: integer
          enum: [0, 1]
          default: 0
        track_clicks:
          type: integer
          enum: [0, 1]
          default: 0
        unsub_show:
          type: integer
          enum: [0, 1]
          default: 0
          description: Add an unsubscribe link to the message.
        unsubscribe_header:
          type: integer
          enum: [0, 1]
          description: Add a `List-Unsubscribe` header, set by `unsubscribe_link` and `unsubscribe_by_email`.
        unsubscribe_link:
          type: integer
          enum: [0, 1]
          description: With `unsubscribe_header`, include an unsubscribe link in the header.
        unsubscribe_by_email:
          type: integer
          enum: [0, 1]
          description: With `unsubscribe_header`, include an unsubscribe email address (`unsubscribe_email`) in the header.
        unsubscribe_email:
          type: string
          format: email
          description: Required when `unsubscribe_by_email` is `1`.
        skip_unconfirmed:
          type: integer
          enum: [0, 1]
          description: Leave out contacts who haven't confirmed their subscription.
        track_duplicate:
          type: integer
          enum: [0, 1]
          default: 0
          description: Double-check that no contact gets the same broadcast twice.
        hourly_speed:
          type: integer
          minimum: -1
          description: The most emails to send per hour.
        threads:
          type: integer
          minimum: 1
          description: How many parallel threads to send with.
        notification_email:
          type: string
          format: email
          description: An address to notify about the schedule.
        response:
          type: string
          enum: ['0', '1']
          description: '`1` returns the created schedule in `response`.'

    # SPIN TAG SCHEMAS
    SpinTag:
      type: object
      properties:
        id:
          type: integer
        place_holder:
          type: string
        tag:
          type: string
          description: Auto-generated tag for use in emails
        word_list:
          type: string
          description: Newline-separated list of words
        user_id:
          type: integer
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time

    SpinTagCreate:
      type: object
      required:
        - place_holder
        - word_list
      properties:
        api_token:
          type: string
        place_holder:
          type: string
          description: Placeholder name (no special characters)
        word_list:
          type: string
          description: Comma-separated list of words to rotate
        response:
          type: string
          enum: ["0", "1"]

    SpinTagUpdate:
      type: object
      required:
        - word_list
      properties:
        api_token:
          type: string
        word_list:
          type: string
          description: Comma-separated list of words
        response:
          type: string
          enum: ["0", "1"]

    # STATISTICS SCHEMAS
    StatsSummary:
      type: object
      properties:
        status:
          type: string
        result:
          type: object
          properties:
            total_sent:
              type: integer
            delivered:
              type: integer
            bounced:
              type: integer
            opened:
              type: integer
            clicked:
              type: integer
            unsubscribed:
              type: integer
            complaints:
              type: integer
            open_rate:
              type: number
              format: float
            click_rate:
              type: number
              format: float
            bounce_rate:
              type: number
              format: float

    StatsDetail:
      type: object
      properties:
        status:
          type: string
        result:
          type: array
          items:
            type: object

    SendingNode:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        provider:
          type: string
        host:
          type: string
        port:
          type: integer
        status:
          type: string
        hourly_limit:
          type: integer
        daily_limit:
          type: integer

    SuppressionAdd:
      type: object
      properties:
        api_token:
          type: string
        emails:
          type: array
          items:
            type: string
            format: email
        domains:
          type: array
          items:
            type: string

    CustomField:
      type: object
      required:
        - name
        - type
      properties:
        api_token:
          type: string
        name:
          type: string
        tag:
          type: string
          description: Merge tag for the field
        type:
          type: string
          enum: [text, number, date, dropdown, checkbox, textarea]
        default_value:
          type: string
        required:
          type: boolean
          default: false
        options:
          type: array
          items:
            type: string
          description: Options for dropdown type

    DripCreate:
      type: object
      required:
        - name
        - list_id
      properties:
        api_token:
          type: string
        name:
          type: string
        list_id:
          type: integer
        trigger_type:
          type: string
          enum: [subscription, date_field, manual]
        emails:
          type: array
          items:
            type: object
            properties:
              subject:
                type: string
              content:
                type: string
              delay_days:
                type: integer
              delay_hours:
                type: integer

    TriggerCreate:
      type: object
      required:
        - name
        - event
        - action
      properties:
        api_token:
          type: string
        name:
          type: string
        event:
          type: string
          enum: [subscribe, unsubscribe, open, click, bounce]
        action:
          type: string
          enum: [send_email, add_to_list, remove_from_list, update_field]
        conditions:
          type: object
        action_params:
          type: object

    Pagination:
      type: object
      properties:
        current_page:
          type: integer
        per_page:
          type: integer
        total:
          type: integer
        total_pages:
          type: integer
        has_more:
          type: boolean
