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

# Lifecycle Actions

> Aplica una acción de ciclo de vida a una Campaña. Acciones válidas: `activate`, `pause`, `archive`, `resume`. La acción es idempotente — aplicar una acción cuando la campaña ya está en el estado destino es un no-op exitoso.

<Info>
  **Rate Limit:** 12 requests per second
</Info>

`action` is one of `activate`, `pause`, `archive`, `resume`.

## Valid Transitions

| Action     | Allowed source statuses        | Effect                     |
| :--------- | :----------------------------- | :------------------------- |
| `activate` | `pending`, `ready`, `cooldown` | sets `status` → `active`   |
| `pause`    | `active`, `cooldown`           | sets `status` → `inactive` |
| `resume`   | `inactive`                     | sets `status` → `active`   |
| `archive`  | any                            | sets `archived = true`     |

## Idempotency

* `archive` is always a success. Re-archiving a campaign is a no-op.
* `pause` on a campaign already `inactive`, and `resume` on a campaign already `active`, are no-op successes.
* `activate` is **not** idempotent: calling it on a campaign already in `active` (or `inactive`, or `finished`) returns `409 INVALID_STATUS_TRANSITION` because `active` is not in the allowed source statuses. Use `resume` to re-activate a paused campaign.

## Errors

* `400 UNKNOWN_ACTION`: `action` is not one of the supported values.
* `402 BILLING_LIMIT_REACHED`: `activate` or `resume` and the plan limit was reached.
* `409 INVALID_STATUS_TRANSITION`: current status is not in the allowed sources. The response includes `current_status` and `valid_targets`.

## Examples

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://api.altur.io/api/v1.0/campaigns/1234/activate" \
    -H "Authorization: api-key YOUR_API_SECRET_KEY"
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      "https://api.altur.io/api/v1.0/campaigns/1234/activate",
      headers={"Authorization": "api-key YOUR_API_SECRET_KEY"},
  )
  response.raise_for_status()
  campaign = response.json()["campaign"]
  ```

  ```javascript JavaScript theme={null}
  const res = await fetch(
    "https://api.altur.io/api/v1.0/campaigns/1234/activate",
    {
      method: "POST",
      headers: { Authorization: "api-key YOUR_API_SECRET_KEY" },
    },
  );
  const { campaign } = await res.json();
  ```
</CodeGroup>


## OpenAPI

````yaml POST /campaigns/{id}/{action}
openapi: 3.0.1
info:
  title: Altur API
  description: >-
    An API aimed to allow third-party developers to interact with the Altur
    platform through a RESTful interface.
  license:
    name: MIT
  version: '1.0'
servers:
  - url: https://api.altur.io/api/v1.0
security:
  - apiKeyAuth: []
paths:
  /campaigns/{id}/{action}:
    post:
      description: >-
        Apply a lifecycle action to a Campaign. Valid actions are `activate`,
        `pause`, `archive` and `resume`. The action is idempotent — applying an
        action when the campaign is already in the target state is a no-op
        success.
      parameters:
        - name: id
          in: path
          description: The identifier of the Campaign
          schema:
            type: integer
          required: true
        - name: action
          in: path
          description: Lifecycle action to apply
          schema:
            type: string
            enum:
              - activate
              - pause
              - archive
              - resume
          required: true
      responses:
        '200':
          description: Lifecycle action applied successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CampaignDetailResponse'
        '400':
          description: Unknown action
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CampaignApiError'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '402':
          description: Billing limit reached (for `activate` / `resume`)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CampaignApiError'
        '404':
          description: Campaign not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CampaignApiError'
        '409':
          description: Invalid status transition for the requested action
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CampaignLifecycleConflictError'
components:
  schemas:
    CampaignDetailResponse:
      type: object
      properties:
        success:
          type: boolean
        campaign:
          $ref: '#/components/schemas/CampaignDetail'
    CampaignApiError:
      type: object
      description: Standard error envelope returned by the v1.0 campaigns API.
      properties:
        success:
          type: boolean
          example: false
        error:
          type: string
          description: Stable, UPPER_SNAKE_CASE error key.
          enum:
            - FORBIDDEN
            - NOT_FOUND
            - RATE_LIMITED
            - SERVER_ERROR
            - INVALID_REQUEST
            - INVALID_STATUS
            - IMMUTABLE_FIELD
            - UNKNOWN_ACTION
            - AGENT_NOT_FOUND
            - INTEGRATION_NOT_FOUND
            - INVALID_INTEGRATION_TYPE
            - INVALID_FILTER_TAG
            - INVALID_PHONE_NUMBER
            - MISSING_CONTACT
            - CONTACT_NOT_FOUND
            - CONTACT_NOT_DELETABLE
            - CAMPAIGN_FINISHED
            - CYCLES_NOT_ENABLED
            - SCHEDULED_MODE_ONLY
            - INVALID_STATUS_TRANSITION
            - BILLING_LIMIT_REACHED
        message:
          type: string
        field:
          type: string
          description: >-
            Set when `error` is `IMMUTABLE_FIELD`; identifies the offending
            field path.
    Error:
      required:
        - error
        - message
      type: object
      properties:
        error:
          type: integer
          format: int32
        message:
          type: string
    CampaignLifecycleConflictError:
      allOf:
        - $ref: '#/components/schemas/CampaignApiError'
        - type: object
          properties:
            current_status:
              type: string
            valid_targets:
              type: array
              items:
                type: string
    CampaignDetail:
      type: object
      description: >-
        Single Campaign detail with nested agent, integration and cycles config.
        The `analytics` field is included only when a snapshot is available for
        the campaign.
      properties:
        id:
          description: Unique identifier for the Campaign
          type: integer
        name:
          description: Name of the Campaign
          type: string
        status:
          description: Current status of the Campaign
          type: string
          enum:
            - pending
            - ready
            - active
            - inactive
            - cooldown
            - finished
        integration:
          description: Nested {id, type} of the integration the Campaign was created on
          type: object
          nullable: true
          properties:
            id:
              type: string
            type:
              type: string
              enum:
                - phone_call
                - whatsapp
        agent:
          type: object
          properties:
            id:
              type: string
              format: uuid4
            name:
              type: string
        created_at:
          type: string
          format: date-time
        scheduling:
          $ref: '#/components/schemas/CampaignSchedule'
        cycles:
          $ref: '#/components/schemas/CampaignCyclesConfig'
        analytics:
          description: >-
            Analytics snapshot for the Campaign. Shape depends on
            `integration.type` — see `CampaignAnalyticsPhoneCall` and
            `CampaignAnalyticsWhatsApp`.
          type: object
    CampaignSchedule:
      type: object
      properties:
        mon:
          $ref: '#/components/schemas/CampaignScheduleDay'
          description: Monday
          type: object
        tue:
          $ref: '#/components/schemas/CampaignScheduleDay'
          description: Tuesday
          type: object
        wed:
          $ref: '#/components/schemas/CampaignScheduleDay'
          description: Wednesday
          type: object
        thu:
          $ref: '#/components/schemas/CampaignScheduleDay'
          description: Thursday
          type: object
        fri:
          $ref: '#/components/schemas/CampaignScheduleDay'
          description: Friday
          type: object
        sat:
          $ref: '#/components/schemas/CampaignScheduleDay'
          description: Saturday
          type: object
        sun:
          $ref: '#/components/schemas/CampaignScheduleDay'
          description: Sunday
          type: object
    CampaignCyclesConfig:
      type: object
      description: Cycles configuration block. Phone-call campaigns only.
      properties:
        enabled:
          type: boolean
          description: Whether cycles are enabled. Immutable after creation.
        mode:
          type: string
          enum:
            - cooldown
            - scheduled
          description: Cycle mode. Immutable after creation.
        max_iterations:
          type: integer
          minimum: 2
          maximum: 12
        cooldown_minutes:
          type: integer
          minimum: 0
          maximum: 1440
        filter_statuses:
          type: array
          items:
            type: string
          description: Contact statuses excluded from the next iteration.
        filter_tags:
          type: array
          items:
            type: string
          description: >-
            Thread tag ids whose contacts are excluded from the next iteration.
            Input-only — not returned on the detail response.
        schedule:
          $ref: '#/components/schemas/CampaignSchedule'
          description: Per-day schedule. Only used when `mode` = `scheduled`.
        schedule_start_date:
          type: string
          format: date
          nullable: true
          description: Only used when `mode` = `scheduled`.
        schedule_end_date:
          type: string
          format: date
          nullable: true
          description: Only used when `mode` = `scheduled`.
    CampaignScheduleDay:
      type: object
      properties:
        startTime:
          description: Start time of the Campaign on Monday
          type: string
        stopTime:
          description: End time of the Campaign on Monday
          type: string
        active:
          description: Boolean describing if the Campaign is active on Monday
          type: boolean
  securitySchemes:
    apiKeyAuth:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        Add `api-key YOUR_API_SECRET_KEY` as the value of the `Authorization`
        header.

````