{
  "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": {
      "get": {
        "description": "Returns all Campaigns for your organization",
        "parameters": [
          {
            "name": "agentId",
            "in": "query",
            "description": "Filters the Campaigns by Agent ID of the agent assigned to the Campaign",
            "schema": {
              "type": "string",
              "format": "uuid4"
            },
            "required": false
          },
          {
            "name": "status",
            "in": "query",
            "description": "Filters the Campaigns by the Status of the Campaign",
            "schema": {
              "type": "string",
              "enum": [
                "pending",
                "ready",
                "active",
                "inactive",
                "cooldown",
                "finished"
              ]
            },
            "required": false
          },
          {
            "name": "integration",
            "in": "query",
            "description": "Type of integration for the Campaign",
            "schema": {
              "type": "string",
              "enum": [
                "phone_call",
                "whatsapp"
              ]
            },
            "required": false
          },
          {
            "name": "startDate",
            "in": "query",
            "description": "Nombre antiguo mantenido por compatibilidad, equivalente a `createdAfter`. Filtra por `created_at`, no por fecha de inicio.",
            "schema": {
              "type": "string",
              "format": "ISO 8601"
            }
          },
          {
            "name": "endDate",
            "in": "query",
            "description": "Nombre antiguo mantenido por compatibilidad, equivalente a `createdBefore`. Filtra por `created_at`, no por fecha de finalización.",
            "schema": {
              "type": "string",
              "format": "ISO 8601"
            },
            "required": false
          },
          {
            "name": "createdAfter",
            "in": "query",
            "description": "Filtra por `created_at` en o después de esta fecha.",
            "schema": {
              "type": "string",
              "format": "ISO 8601"
            },
            "required": false
          },
          {
            "name": "createdBefore",
            "in": "query",
            "description": "Filtra por `created_at` en o antes de esta fecha.",
            "schema": {
              "type": "string",
              "format": "ISO 8601"
            },
            "required": false
          },
          {
            "name": "startedAfter",
            "in": "query",
            "description": "Filtra por `started_at` en o después de esta fecha. Excluye Campañas que aún no han iniciado.",
            "schema": {
              "type": "string",
              "format": "ISO 8601"
            },
            "required": false
          },
          {
            "name": "startedBefore",
            "in": "query",
            "description": "Filtra por `started_at` en o antes de esta fecha. Excluye Campañas que aún no han iniciado.",
            "schema": {
              "type": "string",
              "format": "ISO 8601"
            },
            "required": false
          },
          {
            "name": "endedAfter",
            "in": "query",
            "description": "Filtra por `ended_at` en o después de esta fecha. Excluye Campañas que aún no han finalizado.",
            "schema": {
              "type": "string",
              "format": "ISO 8601"
            },
            "required": false
          },
          {
            "name": "endedBefore",
            "in": "query",
            "description": "Filtra por `ended_at` en o antes de esta fecha. Excluye Campañas que aún no han finalizado.",
            "schema": {
              "type": "string",
              "format": "ISO 8601"
            },
            "required": false
          },
          {
            "name": "archived",
            "in": "query",
            "description": "If true, archived Campaigns will be included in the results.",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "required": false
          },
          {
            "name": "pageSize",
            "in": "query",
            "description": "Number of items per page to return.",
            "schema": {
              "type": "integer",
              "default": 50,
              "maximum": 100
            },
            "required": false
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "Cursor to the next page to return.",
            "schema": {
              "type": "string"
            },
            "required": false
          }
        ],
        "responses": {
          "200": {
            "description": "Campaigns response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CampaignsResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DRFBadRequestError"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "description": "Crea una nueva Campaña para tu organización. Usa `integration_type` para seleccionar entre llamada telefónica o WhatsApp; los campos exclusivos del canal contrario son rechazados.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Llave opcional generada por el cliente (UUID recomendado) para hacer la solicitud idempotente.",
            "schema": {
              "type": "string"
            },
            "required": false
          }
        ],
        "requestBody": {
          "description": "Campaña a crear",
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CampaignCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Campaña creada exitosamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CampaignDetailResponse"
                }
              }
            }
          },
          "400": {
            "description": "Entrada inválida o tipo de integración no soportado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CampaignApiError"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Límite de facturación alcanzado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CampaignApiError"
                }
              }
            }
          },
          "404": {
            "description": "Agente o Integración no encontrados",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CampaignApiError"
                }
              }
            }
          }
        }
      }
    },
    "/campaigns/{id}": {
      "get": {
        "description": "Devuelve el detalle de una Campaña, incluyendo agente, integración, configuración de ciclos y (cuando esté disponible) snapshot de analíticas.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "El identificador de la Campaña",
            "schema": {
              "type": "integer"
            },
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Respuesta de detalle de la Campaña",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CampaignDetailResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Campaña no encontrada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CampaignApiError"
                }
              }
            }
          }
        }
      },
      "patch": {
        "description": "Actualización parcial de una Campaña. Los campos inmutables (`agent_id`, `integration_id`, `integration_type`, `cycles.enabled`, `cycles.mode`) no se pueden modificar y devuelven `IMMUTABLE_FIELD`. Las campañas finalizadas son de solo lectura.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "El identificador de la Campaña",
            "schema": {
              "type": "integer"
            },
            "required": true
          }
        ],
        "requestBody": {
          "description": "Actualización parcial de Campaña",
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CampaignUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Campaña actualizada exitosamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CampaignDetailResponse"
                }
              }
            }
          },
          "400": {
            "description": "Entrada inválida, campo inmutable, ciclos no habilitados, o uso indebido de campos exclusivos del modo `scheduled`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CampaignApiError"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Campaña no encontrada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CampaignApiError"
                }
              }
            }
          },
          "409": {
            "description": "Campaña finalizada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CampaignApiError"
                }
              }
            }
          }
        }
      }
    },
    "/campaigns/{id}/{action}": {
      "post": {
        "description": "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.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "El identificador de la Campaña",
            "schema": {
              "type": "integer"
            },
            "required": true
          },
          {
            "name": "action",
            "in": "path",
            "description": "Acción de ciclo de vida a aplicar",
            "schema": {
              "type": "string",
              "enum": [
                "activate",
                "pause",
                "archive",
                "resume"
              ]
            },
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Acción aplicada exitosamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CampaignDetailResponse"
                }
              }
            }
          },
          "400": {
            "description": "Acción desconocida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CampaignApiError"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Límite de facturación alcanzado (para `activate` / `resume`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CampaignApiError"
                }
              }
            }
          },
          "404": {
            "description": "Campaña no encontrada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CampaignApiError"
                }
              }
            }
          },
          "409": {
            "description": "Transición de estado inválida para la acción",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CampaignLifecycleConflictError"
                }
              }
            }
          }
        }
      }
    },
    "/campaigns/{id}/contacts": {
      "get": {
        "description": "Returns the Campaign Contacts corresponding to the given identifier",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The identifier of the Campaign to return the Contacts",
            "schema": {
              "type": "integer"
            },
            "required": true
          },
          {
            "name": "status",
            "in": "query",
            "description": "Filters the Campaign Contacts by the Status of the Campaign Contact",
            "schema": {
              "type": "string",
              "enum": [
                "queue",
                "sending",
                "sent",
                "delivered",
                "voicemail",
                "read",
                "failed",
                "retrying",
                "converted",
                "answered",
                "accepted",
                "rejected"
              ]
            },
            "required": false
          },
          {
            "name": "pageSize",
            "in": "query",
            "description": "Number of items per page to return.",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 100
            },
            "required": false
          },
          {
            "name": "pageIndex",
            "in": "query",
            "description": "Page number to the next page to return.",
            "schema": {
              "type": "integer",
              "default": 0,
              "maximum": 25000,
              "minimum": 0
            },
            "required": false
          }
        ],
        "responses": {
          "200": {
            "description": "Campaign Contacts response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CampaignContactsResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DRFBadRequestError"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Campaign not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "description": "Crea Contactos de Campaña por lotes. Hasta 1000 contactos por solicitud. Cada item se procesa de forma independiente (una fila inválida no rompe el lote) y se devuelve un `summary` agregado y `results` por item. Usa `if_duplicate` para controlar el comportamiento cuando un contacto ya existe en la campaña (`skip` mantiene el original, `update` sobreescribe los campos mutables).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "El identificador de la Campaña",
            "schema": {
              "type": "integer"
            },
            "required": true
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Llave opcional generada por el cliente (UUID recomendado) para hacer la solicitud idempotente.",
            "schema": {
              "type": "string"
            },
            "required": false
          }
        ],
        "requestBody": {
          "description": "Lote de contactos a crear",
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CampaignContactBatchCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Lote procesado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CampaignContactBatchResponse"
                }
              }
            }
          },
          "400": {
            "description": "Solicitud inválida",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DRFBadRequestError"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Campaña no encontrada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CampaignApiError"
                }
              }
            }
          }
        }
      }
    },
    "/campaigns/{id}/contacts/{contact_id}": {
      "get": {
        "description": "Devuelve el detalle de un contacto dentro de una Campaña.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "El identificador de la Campaña",
            "schema": {
              "type": "integer"
            },
            "required": true
          },
          {
            "name": "contact_id",
            "in": "path",
            "description": "El identificador del contacto dentro de la Campaña",
            "schema": {
              "type": "integer"
            },
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Detalle del contacto",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CampaignContactDetailResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Campaña o contacto no encontrados",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CampaignApiError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "description": "Elimina un contacto de una Campaña. Solo se pueden eliminar contactos en estado `queue` o `failed`; cualquier otro estado devuelve `CONTACT_NOT_DELETABLE` (409).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "El identificador de la Campaña",
            "schema": {
              "type": "integer"
            },
            "required": true
          },
          {
            "name": "contact_id",
            "in": "path",
            "description": "El identificador del contacto dentro de la Campaña",
            "schema": {
              "type": "integer"
            },
            "required": true
          }
        ],
        "responses": {
          "204": {
            "description": "Contacto eliminado exitosamente"
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Campaña o contacto no encontrados",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CampaignApiError"
                }
              }
            }
          },
          "409": {
            "description": "El contacto no está en un estado eliminable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CampaignApiError"
                }
              }
            }
          }
        }
      }
    },
    "/campaigns/{id}/calls": {
      "get": {
        "description": "Returns a paginated list of calls for a specific campaign",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The identifier of the Campaign to return the Calls",
            "schema": {
              "type": "integer"
            },
            "required": true
          },
          {
            "name": "status",
            "in": "query",
            "description": "Filters the Campaign Calls by the status of the Call",
            "schema": {
              "type": "string",
              "enum": [
                "ended",
                "failed",
                "busy",
                "no-answer",
                "in-progress"
              ]
            },
            "required": false
          },
          {
            "name": "answeredBy",
            "in": "query",
            "description": "Filters the Campaign Calls by who answered the call",
            "schema": {
              "type": "string",
              "enum": [
                "human",
                "machine",
                "unknown"
              ]
            },
            "required": false
          },
          {
            "name": "startDate",
            "in": "query",
            "description": "Filter calls created after this date in ISO 8601 format",
            "schema": {
              "type": "string",
              "format": "ISO 8601"
            },
            "required": false
          },
          {
            "name": "endDate",
            "in": "query",
            "description": "Filter calls created before this date in ISO 8601 format",
            "schema": {
              "type": "string",
              "format": "ISO 8601"
            },
            "required": false
          },
          {
            "name": "pageSize",
            "in": "query",
            "description": "Number of items per page to return.",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 100
            },
            "required": false
          },
          {
            "name": "pageIndex",
            "in": "query",
            "description": "Page number to return (0-based).",
            "schema": {
              "type": "integer",
              "default": 0,
              "maximum": 25000,
              "minimum": 0
            },
            "required": false
          }
        ],
        "responses": {
          "200": {
            "description": "Campaign Calls response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CampaignCallsResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DRFBadRequestError"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Campaign not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/enduser": {
      "post": {
        "description": "Create new EndUser for your organization",
        "requestBody": {
          "description": "EndUser to be created",
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EndUserData"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "EndUser created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EndUser"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/enduser/{id}": {
      "get": {
        "description": "Returns the EndUser corresponding to the given identifier",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The identifier of the EndUser to return",
            "schema": {
              "type": "string",
              "format": "uuid4"
            },
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "EndUser response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EndUser"
                }
              }
            }
          },
          "400": {
            "description": "Unexpected error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "EndUser not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "put": {
        "description": "Updates the details of an EndUser",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The identifier of the EndUser to update",
            "schema": {
              "type": "string",
              "format": "uuid4"
            },
            "required": true
          }
        ],
        "requestBody": {
          "description": "EndUser object that needs to be updated",
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EndUserData"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "EndUser updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EndUser"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "EndUser not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "description": "Deletes an EndUser",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The identifier of the EndUser to delete",
            "schema": {
              "type": "string",
              "format": "uuid4"
            },
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "EndUser deleted successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResponseMessage"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "EndUser not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/thread/{id}": {
      "get": {
        "description": "Returns the Thread corresponding to the given identifier",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The identifier of the Thread to return",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Thread response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Thread"
                }
              }
            }
          },
          "400": {
            "description": "Unexpected error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Thread not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/message": {
      "post": {
        "description": "Sends Message to the Thread between a Agent and an EndUser, returns the Message created from the request, the Messages generated in response, and returns information about the Thread between the Agent and EndUser",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agent_id": {
                    "description": "Unique identifier of the Agent receiving the Message",
                    "type": "string",
                    "format": "uuid4"
                  },
                  "end_user_id": {
                    "description": "Unique identifier of the EndUser sending the Message",
                    "type": "string",
                    "format": "uuid4"
                  },
                  "content": {
                    "description": "Text content of the Message",
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Thread response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageResponse"
                }
              }
            }
          },
          "400": {
            "description": "Unexpected error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Agent or EndUser not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/message/{thread_id}": {
      "get": {
        "description": "Get all Messages in a Thread, ordered from oldest to most recently sent",
        "parameters": [
          {
            "name": "thread_id",
            "in": "path",
            "description": "The identifier of the Thread to fetch",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Array containing all Messages in the Thread",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Message"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Unexpected error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Thread not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/call": {
      "post": {
        "description": "Starts a Call",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agent_id": {
                    "description": "Unique identifier of the Agent that will participate in the Call (formerly Chatbot or Assistant)",
                    "type": "string",
                    "format": "uuid4"
                  },
                  "phone_number_to": {
                    "description": "E.164 formatted phone number of the EndUser to call",
                    "type": "string",
                    "format": "e164"
                  },
                  "end_user_display_name": {
                    "description": "Display name of the EndUser to call",
                    "type": "string"
                  },
                  "end_user_context": {
                    "description": "Context of the EndUser to call",
                    "oneOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "object"
                      }
                    ]
                  },
                  "initial_message": {
                    "description": "Initial message the Agent will say upon the call being answered",
                    "type": "string"
                  }
                },
                "required": [
                  "agent_id",
                  "phone_number_to"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Call response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Call"
                }
              }
            }
          },
          "400": {
            "description": "Unexpected error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Agent not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/call/{id}": {
      "get": {
        "description": "Returns the Call corresponding to the given identifier",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The identifier of the Call to return",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "Call response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Call"
                }
              }
            }
          },
          "400": {
            "description": "Unexpected error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Call not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/call/{id}/recording": {
      "get": {
        "description": "Access the recording of a Call in form of a file stream",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The identifier of the Call to fetch",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "File stream of the Call recording",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "400": {
            "description": "Unexpected error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Call not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Agent":{
        "type": "object",
        "properties": {
          "id": {
            "description": "Unique identifier for the Agent",
            "type": "string",
            "format": "uuid4"
          },
          "name": {
            "description": "Name of the Agent",
            "type": "string"
          }
        }
      },
      "Campaign": {
        "type": "object",
        "properties": {
          "id": {
            "description": "Unique identifier for the Campaign",
            "type": "integer"
          },
          "name": {
            "description": "Name of the Campaign",
            "type": "string"
          },
          "description": {
            "description": "Description of the Campaign",
            "type": "string"
          },
          "status": {
            "description": "The current status of the Campaign",
            "type": "string"
          },
          "created_at": {
            "description": "The date and time when the Campaign was created",
            "type": "string",
            "format": "ISO 8601"
          },
          "started_at": {
            "description": "The date and time when the Campaign was started",
            "type": "string",
            "format": "ISO 8601",
            "nullable": true
          },
          "ended_at": {
            "description": "The date and time when the Campaign ended",
            "type": "string",
            "format": "ISO 8601",
            "nullable": true
          },
          "agent": {
            "description": "The agent assigned to the Campaign",
            "type": "object",
            "$ref": "#/components/schemas/Agent"
          },
          "scheduling": {
            "description": "The schedule of the Campaign",
            "type": "object",
            "$ref": "#/components/schemas/CampaignSchedule"
          },
          "timezone": {
            "description": "The timezone of the Campaign",
            "type": "string"
          },
          "retries": {
            "description": "The number of times the campaign will retry to contact a contact if the call or message fails",
            "type": "integer"
          },
          "archived": {
            "description": "Whether the Campaign is archived",
            "type": "boolean"
          },
          "template": {
            "description": "WhatsApp Template assigned to the Campaign (WhatsApp campaigns only)",
            "type": "string"
          },
          "first_message": {
            "description": "The first message the Agent will say upon the call being answered (Phone call campaigns only)",
            "type": "string"
          },
          "concurrency_limit": {
            "description": "The maximum number of concurrent calls allowed (Phone call campaigns only)",
            "type": "integer"
          },
          "cycle_enabled": {
            "description": "If enabled the campaign will automatically rerun and re-contact contacts (Phone call campaigns only)",
            "type": "boolean"
          },
          "cycle_max_iterations": {
            "description": "The maximum number of times a campaign will retry to contact a contact if the call fails (Phone call campaigns only)",
            "type": "integer"
          },
          "cycle_cooldown_minutes": {
            "description": "The cooldown time between cycles of the campaign in minutes (Phone call campaigns only)",
            "type": "integer"
          },
          "cycle_filter_statuses": {
            "description": "The list of contact statuses to exclude from the campaign on cycles (Phone call campaigns only)",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "cycle_filter_tags": {
            "description": "The list of contact tags assigned to the contacts to exclude from the campaign on cycles (Phone call campaigns only)",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "cycle_current_iteration": {
            "description": "Current iteration of the Campaign (Phone call campaigns only)",
            "type": "integer"
          },
          "cycle_last_iteration_at": {
            "description": "Last iteration of the Campaign (Phone call campaigns only)",
            "type": "string",
            "format": "ISO 8601"
          }
        }
      },
      "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"
          }
        }
      },
      "CampaignSchedule":{
        "type": "object",
        "properties": {
          "mon": {
            "description": "Monday",
            "type": "object",
            "$ref": "#/components/schemas/CampaignScheduleDay"
          },
          "tue": {
            "description": "Tuesday",
            "type": "object",
            "$ref": "#/components/schemas/CampaignScheduleDay"
          },
          "wed": {
            "description": "Wednesday",
            "type": "object",
            "$ref": "#/components/schemas/CampaignScheduleDay"
          },
          "thu": {
            "description": "Thursday",
            "type": "object",
            "$ref": "#/components/schemas/CampaignScheduleDay"
          },
          "fri": {
            "description": "Friday",
            "type": "object",
            "$ref": "#/components/schemas/CampaignScheduleDay"
          },
          "sat": {
            "description": "Saturday",
            "type": "object",
            "$ref": "#/components/schemas/CampaignScheduleDay"
          },
          "sun": {
            "description": "Sunday",
            "type": "object",
            "$ref": "#/components/schemas/CampaignScheduleDay"
          }
        }
      },
      "CampaignsResponse": {
        "type": "object",
        "properties": {
          "total_count": {
            "description": "Total number of Campaigns for the given query. NOTE: The result is cache for 3 minutes.",
            "type": "integer"
          },
          "campaigns": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Campaign"
            }
          },
          "pagination": {
            "type": "object",
            "$ref": "#/components/schemas/CursorPagination"
          }
        }
      },
      "CampaignCallsResponse": {
        "type": "object",
        "properties": {
          "total_count": {
            "description": "Total number of Campaign Calls for the given query.",
            "type": "integer"
          },
          "calls": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CampaignCall"
            }
          },
          "pagination": {
            "type": "object",
            "$ref": "#/components/schemas/CampaignCallsPagination"
          }
        }
      },
      "CampaignCall": {
        "type": "object",
        "properties": {
          "id": {
            "description": "Unique identifier for the Call",
            "type": "string"
          },
          "thread_id": {
            "description": "Identificador único del Thread al que pertenece la llamada",
            "type": "string"
          },
          "type": {
            "description": "Type of the Call",
            "type": "string",
            "enum": ["inbound", "outbound"]
          },
          "status": {
            "description": "Status of the Call",
            "type": "string",
            "enum": ["ended", "failed", "busy", "no-answer", "in-progress"]
          },
          "answered_by": {
            "description": "Who or what answered the Call",
            "type": "string",
            "enum": ["human", "machine", "unknown"],
            "nullable": true
          },
          "created_at": {
            "description": "Datetime when the Call was created (ISO 8601)",
            "type": "string",
            "format": "date-time"
          },
          "started_at": {
            "description": "Datetime when the Call was started (ISO 8601)",
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "ended_at": {
            "description": "Datetime when the Call ended (ISO 8601)",
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "ended_by": {
            "description": "Who ended the Call (agent, user or system). Empty if the call never connected",
            "type": "string",
            "enum": ["agent", "user", "system", ""]
          },
          "ended_reason": {
            "description": "Brief reason why the Call ended. Empty if not available",
            "type": "string"
          },
          "duration": {
            "description": "Duration of the Call in seconds",
            "type": "integer"
          },
          "billed_duration": {
            "description": "Billed duration of the Call in seconds",
            "type": "integer"
          },
          "contact": {
            "description": "The contact associated with this call",
            "type": "object",
            "$ref": "#/components/schemas/CampaignCallContact"
          },
          "extracted_data": {
            "description": "Key-value pairs extracted from the call conversation",
            "type": "object",
            "example": {
              "interested": "yes",
              "appointment_date": "2024-01-20"
            }
          },
          "tags": {
            "description": "Tags assigned to the Call",
            "type": "array",
            "items": {
              "type": "string"
            },
            "example": ["interested", "callback"]
          },
          "recording_url": {
            "description": "URL to fetch the call recording",
            "type": "string",
            "example": "/api/v1.0/call/call_abc123def456/recording"
          },
          "policy_evaluation": {
            "description": "Resultados de la evaluación de cumplimiento de políticas",
            "$ref": "#/components/schemas/PolicyEvaluation"
          }
        }
      },
      "CampaignCallContact": {
        "type": "object",
        "properties": {
          "id": {
            "description": "Internal Campaign Contact ID",
            "type": "integer"
          },
          "f_id": {
            "description": "External/foreign ID (your reference)",
            "type": "string"
          },
          "name": {
            "description": "Contact name",
            "type": "string"
          },
          "phone_number": {
            "description": "Phone number in E.164 format",
            "type": "string"
          },
          "status": {
            "description": "Contact status in the campaign",
            "type": "string"
          }
        }
      },
      "CampaignCallsPagination": {
        "type": "object",
        "description": "Pagination information for campaign calls",
        "properties": {
          "page_index": {
            "type": "integer",
            "description": "Current page index"
          },
          "page_size": {
            "type": "integer",
            "description": "Number of items per page"
          },
          "has_next": {
            "type": "boolean",
            "description": "Whether there are more pages available"
          },
          "has_previous": {
            "type": "boolean",
            "description": "Whether there are previous pages"
          },
          "next_page": {
            "type": "integer",
            "description": "Index of the next page (null if no more pages)",
            "nullable": true
          },
          "previous_page": {
            "type": "integer",
            "description": "Index of the previous page (null if no previous pages)",
            "nullable": true
          }
        }
      },
      "CampaignContactsResponse": {
        "type": "object",
        "properties": {
          "total_count": {
            "description": "Total number of Campaign Contacts for the given query. NOTE: Only calculated in the first page.",
            "type": "integer"
          },
          "contacts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CampaignContact"
            }
          },
          "pagination": {
            "type": "object",
            "$ref": "#/components/schemas/OffsetPagination"
          }
        }
      },
      "CampaignDetail": {
        "type": "object",
        "description": "Detalle de una Campaña con agente, integración y configuración de ciclos anidados. El campo `analytics` se incluye solo cuando hay snapshot disponible.",
        "properties": {
          "id": {
            "description": "Identificador único de la Campaña",
            "type": "integer"
          },
          "name": {
            "description": "Nombre de la Campaña",
            "type": "string"
          },
          "status": {
            "description": "Estado actual de la Campaña",
            "type": "string",
            "enum": [
              "pending",
              "ready",
              "active",
              "inactive",
              "cooldown",
              "finished"
            ]
          },
          "integration": {
            "description": "Objeto {id, type} de la integración sobre la que se creó la Campaña",
            "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": "Snapshot de analíticas. La forma depende de `integration.type`.",
            "type": "object"
          }
        }
      },
      "CampaignDetailResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "campaign": {
            "$ref": "#/components/schemas/CampaignDetail"
          }
        }
      },
      "CampaignCyclesConfig": {
        "type": "object",
        "description": "Bloque de configuración de ciclos. Solo aplicable a campañas de llamada telefónica.",
        "properties": {
          "enabled": {
            "type": "boolean",
            "description": "Si los ciclos están habilitados. Inmutable después de la creación."
          },
          "mode": {
            "type": "string",
            "enum": [
              "cooldown",
              "scheduled"
            ],
            "description": "Modo del ciclo. Inmutable después de la creación."
          },
          "max_iterations": {
            "type": "integer",
            "minimum": 2,
            "maximum": 12
          },
          "cooldown_minutes": {
            "type": "integer",
            "minimum": 0,
            "maximum": 1440
          },
          "filter_statuses": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Estados de contactos excluidos de la siguiente iteración."
          },
          "filter_tags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "IDs de tags de hilo cuyos contactos se excluyen de la siguiente iteración. Solo de entrada; no se devuelve en la respuesta de detalle."
          },
          "schedule": {
            "$ref": "#/components/schemas/CampaignSchedule",
            "description": "Horario por día. Solo se usa cuando `mode` = `scheduled`."
          },
          "schedule_start_date": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Solo se usa cuando `mode` = `scheduled`."
          },
          "schedule_end_date": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Solo se usa cuando `mode` = `scheduled`."
          }
        }
      },
      "CampaignCreate": {
        "type": "object",
        "required": [
          "name",
          "agent_id",
          "integration_id",
          "integration_type"
        ],
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 255
          },
          "description": {
            "type": "string"
          },
          "agent_id": {
            "type": "string",
            "format": "uuid4",
            "description": "`public_id` del agente que será dueño de esta campaña."
          },
          "integration_id": {
            "type": "string",
            "description": "`public_id` de la integración a usar. Debe pertenecer a `agent_id`."
          },
          "integration_type": {
            "type": "string",
            "enum": [
              "phone_call",
              "whatsapp"
            ]
          },
          "timezone": {
            "type": "string",
            "description": "Timezone IANA. Por defecto `America/Mexico_City`."
          },
          "retries": {
            "type": "integer",
            "minimum": 0,
            "maximum": 5,
            "default": 1
          },
          "message_limit": {
            "type": "integer",
            "minimum": 1,
            "maximum": 10000,
            "default": 250
          },
          "first_message": {
            "type": "string",
            "description": "Primer mensaje del Agente al ser contestada la llamada. Solo para `phone_call`."
          },
          "template": {
            "type": "string",
            "description": "Nombre del template de WhatsApp. Solo para `whatsapp`."
          },
          "template_alt": {
            "type": "string",
            "description": "Nombre del template alternativo. Solo para `whatsapp`."
          },
          "scheduling": {
            "$ref": "#/components/schemas/CampaignSchedule"
          },
          "cycles": {
            "$ref": "#/components/schemas/CampaignCyclesConfig"
          }
        }
      },
      "CampaignUpdate": {
        "type": "object",
        "description": "Actualización parcial. Cualquier campo puede omitirse. Los campos inmutables (`agent_id`, `integration_id`, `integration_type`, `cycles.enabled`, `cycles.mode`) no pueden incluirse.",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 255
          },
          "description": {
            "type": "string"
          },
          "timezone": {
            "type": "string"
          },
          "retries": {
            "type": "integer",
            "minimum": 0,
            "maximum": 5
          },
          "message_limit": {
            "type": "integer",
            "minimum": 1,
            "maximum": 10000
          },
          "scheduling": {
            "$ref": "#/components/schemas/CampaignSchedule"
          },
          "first_message": {
            "type": "string"
          },
          "template": {
            "type": "string"
          },
          "template_alt": {
            "type": "string"
          },
          "cycles": {
            "$ref": "#/components/schemas/CampaignCyclesConfig"
          }
        }
      },
      "CampaignContactBatchCreate": {
        "type": "object",
        "required": [
          "contacts"
        ],
        "properties": {
          "contacts": {
            "type": "array",
            "minItems": 1,
            "maxItems": 1000,
            "items": {
              "type": "object",
              "required": [
                "contact"
              ],
              "properties": {
                "contact": {
                  "type": "string",
                  "description": "Número de teléfono, normalizado a E.164 al insertar."
                },
                "name": {
                  "type": "string"
                },
                "context": {
                  "type": "string"
                },
                "extracted_data": {
                  "type": "object"
                },
                "f_id": {
                  "type": "string",
                  "description": "Identificador externo del contacto en tu sistema."
                }
              }
            }
          },
          "if_duplicate": {
            "type": "string",
            "enum": [
              "skip",
              "update"
            ],
            "default": "skip",
            "description": "Comportamiento cuando el número del contacto ya existe en la campaña."
          }
        }
      },
      "CampaignContactBatchResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "summary": {
            "type": "object",
            "properties": {
              "created": {
                "type": "integer"
              },
              "updated": {
                "type": "integer"
              },
              "skipped_duplicate": {
                "type": "integer"
              },
              "failed": {
                "type": "integer"
              }
            }
          },
          "results": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "index": {
                  "type": "integer"
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "created",
                    "updated",
                    "skipped_duplicate",
                    "failed"
                  ]
                },
                "id": {
                  "type": "string",
                  "description": "Presente cuando status es `created`, `updated` o `skipped_duplicate`."
                },
                "contact": {
                  "type": "string"
                },
                "error": {
                  "type": "string",
                  "description": "Presente cuando status es `failed`. Uno de `INVALID_PHONE_NUMBER`, `MISSING_CONTACT`, `SERVER_ERROR`."
                }
              }
            }
          }
        }
      },
      "CampaignContactDetailResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "contact": {
            "$ref": "#/components/schemas/CampaignContact"
          }
        }
      },
      "CampaignApiError": {
        "type": "object",
        "description": "Envelope de error estándar de la API v1.0 de campañas.",
        "properties": {
          "success": {
            "type": "boolean",
            "example": false
          },
          "error": {
            "type": "string",
            "description": "Llave de error estable en UPPER_SNAKE_CASE.",
            "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": "Presente cuando `error` es `IMMUTABLE_FIELD`; identifica el campo en conflicto."
          }
        }
      },
      "CampaignLifecycleConflictError": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CampaignApiError"
          },
          {
            "type": "object",
            "properties": {
              "current_status": {
                "type": "string"
              },
              "valid_targets": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          }
        ]
      },
      "EndUser": {
        "type": "object",
        "properties": {
          "id": {
            "description": "Unique identifier for the EndUser",
            "type": "string",
            "format": "uuid4"
          },
          "display_name": {
            "description": "EndUser's display name",
            "type": "string"
          },
          "integration_type": {
            "description": "Enum representing the Integration's channel",
            "type": "string",
            "enum": [
              "api",
              "whatsapp"
            ]
          },
          "info": {
            "description": "EndUser's information valuable for interactions with Agents or human agents",
            "type": "string"
          }
        },
        "required": [
          "id",
          "display_name",
          "integration"
        ]
      },
      "EndUserData": {
        "type": "object",
        "properties": {
          "display_name": {
            "description": "EndUser's display name",
            "type": "string"
          },
          "info": {
            "description": "EndUser's information valuable for interactions with Agents or human agents",
            "type": "string"
          }
        }
      },
      "Integration": {
        "type": "object",
        "properties": {
          "id": {
            "description": "Unique identifier for the Integration",
            "type": "string"
          },
          "type": {
            "description": "Enum representing the Integration's channel",
            "type": "string",
            "enum": [
              "api",
              "whatsapp"
            ]
          }
        },
        "required": [
          "id",
          "type"
        ]
      },
      "Tag": {
        "type": "object",
        "properties": {
          "id": {
            "description": "Unique identifier for the Tag",
            "type": "string"
          },
          "name": {
            "description": "Name given to the Tag",
            "type": "string"
          },
          "color": {
            "description": "Color used for in-app display of Tag",
            "type": "string",
            "enum": [
              "blue",
              "green",
              "red",
              "pink",
              "purple",
              "orange",
              "yellow"
            ]
          }
        },
        "required": [
          "id",
          "name",
          "color"
        ]
      },
      "User": {
        "type": "object",
        "properties": {
          "id": {
            "description": "Unique identifier for the User",
            "type": "string"
          },
          "email": {
            "description": "User's email address",
            "type": "string"
          },
          "first_name": {
            "description": "User's first name",
            "type": "string"
          },
          "last_name": {
            "description": "User's last name",
            "type": "string"
          }
        },
        "required": [
          "id",
          "email"
        ]
      },
      "Thread": {
        "type": "object",
        "properties": {
          "id": {
            "description": "Unique identifier for the Thread",
            "type": "string"
          },
          "agent": {
            "$ref": "#/components/schemas/Agent"
          },
          "end_user": {
            "$ref": "#/components/schemas/EndUser"
          },
          "integration": {
            "$ref": "#/components/schemas/Integration"
          },
          "updated_at": {
            "description": "Last time the Thread was updated",
            "type": "string",
            "format": "date-time"
          },
          "active": {
            "description": "Boolean describing if automatic responses by the Agent are active on this Thread",
            "type": "boolean"
          },
          "blocked": {
            "description": "Boolean describing if Thread is blocked",
            "type": "boolean"
          },
          "tags": {
            "description": "Tags assigned to Thread",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Tag"
            }
          },
          "assigned_to": {
            "description": "Users assigned to Thread",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/User"
            }
          }
        }
      },
      "Call": {
        "type": "object",
        "properties": {
          "id": {
            "description": "Unique identifier for the Call",
            "type": "string"
          },
          "thread_id": {
            "description": "Identificador único del Thread al que pertenece la llamada",
            "type": "string"
          },
          "thread": {
            "$ref": "#/components/schemas/Thread"
          },
          "type": {
            "description": "Type of the Call",
            "type": "string",
            "enum": [
              "inbound",
              "outbound"
            ]
          },
          "status": {
            "description": "Status of the Call",
            "type": "string",
            "enum": [
              "created",
              "queued",
              "ringing",
              "in-progress",
              "forwarding",
              "ended",
              "busy",
              "no-answer",
              "failed"
            ]
          },
          "answered_by": {
            "description": "Who or what answered the Call",
            "type": "string",
            "enum": [
              "human",
              "machine",
              "unknown"
            ]
          },
          "created_at": {
            "description": "Datetime from when the Call was created",
            "type": "string",
            "format": "date-time"
          },
          "started_at": {
            "description": "Datetime from when the Call was started",
            "type": "string",
            "format": "date-time"
          },
          "ended_at": {
            "description": "Datetime from when the Call was ended",
            "type": "string",
            "format": "date-time"
          },
          "ended_by": {
            "description": "Who ended the Call (agent, user or system). Empty if the call never connected",
            "type": "string",
            "enum": [
              "agent",
              "user",
              "system",
              ""
            ]
          },
          "ended_reason": {
            "description": "Brief reason why the Call ended. Empty if not available",
            "type": "string"
          },
          "duration": {
            "description": "Duration of the Call in seconds",
            "type": "integer"
          },
          "billed_duration": {
            "description": "Billed duration of the Call in seconds",
            "type": "integer"
          },
          "policy_evaluation": {
            "description": "Resultados de la evaluación de cumplimiento de políticas",
            "$ref": "#/components/schemas/PolicyEvaluation"
          }
        }
      },
      "MessageResponse": {
        "type": "object",
        "properties": {
          "thread": {
            "$ref": "#/components/schemas/Thread"
          },
          "messages": {
            "description": "Array of Messages in response to prompted Message",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Message"
            }
          },
          "in_response_to": {
            "$ref": "#/components/schemas/Message"
          }
        }
      },
      "Message": {
        "type": "object",
        "properties": {
          "thread_id": {
            "description": "Unique identifier of the Thread the Message belongs to",
            "type": "string"
          },
          "type": {
            "description": "Message type enum",
            "type": "string",
            "enum": [
              "text",
              "image",
              "audio",
              "video",
              "button",
              "template",
              "document"
            ]
          },
          "content": {
            "description": "Message's text content",
            "type": "string"
          },
          "media": {
            "description": "Message's media content, if any (usually in form of URL)",
            "type": "string"
          },
          "sent_by": {
            "description": "Author of this message",
            "type": "string",
            "enum": [
              "AI",
              "EU",
              "SYS"
            ]
          },
          "sent_by_user": {
            "description": "Altur user id (if Message was sent manually by an in-app user)",
            "type": "string"
          },
          "sent_at": {
            "description": "Datetime from when the Message was sent",
            "type": "string",
            "format": "date-time"
          },
          "read": {
            "description": "Boolean describing if the Message is considered as read",
            "type": "boolean"
          }
        },
        "required": [
          "thread_id",
          "type",
          "sent_by",
          "sent_at"
        ]
      },
      "DRFBadRequestError":{
        "type": "object",
        "description": "Validation error response where each field name that has an error is a property containing an array of error messages",
        "additionalProperties": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "example": {
          "field1": ["This field is required."],
          "field2": ["Incorrect format."],
          "non_field_errors": ["The date range is not valid."]
        }
      },
      "Error": {
        "required": [
          "error",
          "message"
        ],
        "type": "object",
        "properties": {
          "error": {
            "type": "integer",
            "format": "int32"
          },
          "message": {
            "type": "string"
          }
        }
      },
      "ResponseMessage": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          }
        }
      },
      "CampaignContact": {
        "type": "object",
        "properties": {
          "f_id": {
            "description": "Unique External identifier for the Campaign Contact",
            "type": "string"
          },
          "id": {
            "description": "Unique identifier for the Campaign Contact",
            "type": "integer"
          },
          "name": {
            "description": "Name of the Campaign Contact",
            "type": "string"
          },
          "contact": {
            "description": "Phone number of the contact",
            "type": "string"
          },
          "status": {
            "description": "Status of the Campaign Contact",
            "type": "string"
          },
          "context": {
            "description": "Context of the Campaign Contact",
            "type": "string"
          },
          "retries": {
            "description": "Voicemail retries of the Campaign Contact",
            "type": "integer"
          },
          "has_follow_up":{
            "description": "Boolean describing if the Campaign Contact has a follow up scheduled",
            "type": "boolean"
          },
          "call_count":{
            "description": "Number of calls made to the Campaign Contact",
            "type": "integer"
          },
          "billed_duration":{
            "description": "The total billed duration of the Campaign Contact Calls in seconds",
            "type": "integer",
            "example": 270
          },
          "last_call_at":{
            "description": "The datetime of the last call made to the Campaign Contact",
            "type": "string",
            "example": "2025-10-03 19:11:39"
          },
          "extracted_data": {
            "description": "Extracted data of the Campaign Contact",
            "type": "object",
            "example": {
              "monto_prometido": "1000",
              "fecha_limite": "01-01-2025"
            }
          },
          "tags":{
            "description": "Tags assigned to the Campaign Contact",
            "type": "array",
            "items": {
              "type": "string"
            },
            "example": [
              "tag1",
              "tag2"
            ]
          }
        }
      },
      "CursorPagination": {
        "type": "object",
        "description": "Filters are applied to each request independently. Changing filters while paginating may result in gaps or overlaps in the result set. For consistent results, maintain the same filters throughout pagination.",
        "properties": {
          "has_next": {
            "type": "boolean",
            "description": "Boolean describing if there are more items to fetch"
          },
          "has_previous": {
            "type": "boolean",
            "description": "Boolean describing if there are previous items to fetch"
          },
          "next_cursor": {
            "type": "string",
            "description": "Cursor to the next page to return"
          },
          "previous_cursor": {
            "type": "string",
            "description": "Cursor to the previous page to return"
          }
        }
      },
      "PolicyEvaluation": {
        "type": "object",
        "description": "Resultados de la evaluación de cumplimiento de políticas para una llamada. Los campos de puntuación y conteo serán null cuando la llamada no ha sido evaluada (ej: no fue muestreada, no hay políticas activas, o la evaluación está pendiente). El arreglo de políticas estará vacío en estos casos.",
        "properties": {
          "score": {
            "description": "Puntuación de cumplimiento de 0 a 10. Fórmula: (políticas_cumplidas / políticas_aplicables) * 10. Null si no hay políticas aplicables o la evaluación no se ejecutó.",
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "policies_evaluated_count": {
            "description": "Número total de políticas evaluadas",
            "type": "integer",
            "nullable": true
          },
          "policies_met_count": {
            "description": "Número de políticas que fueron cumplidas",
            "type": "integer",
            "nullable": true
          },
          "policies_not_applicable_count": {
            "description": "Número de políticas marcadas como no aplicables",
            "type": "integer",
            "nullable": true
          },
          "completed": {
            "description": "Si la evaluación de políticas ha sido completada",
            "type": "boolean"
          },
          "completed_at": {
            "description": "Cuándo se completó la evaluación",
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "policies": {
            "description": "Resultados de evaluación por política",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PolicyEvaluationItem"
            }
          }
        }
      },
      "PolicyEvaluationItem": {
        "type": "object",
        "description": "Resultado individual de evaluación de política",
        "properties": {
          "policy_id": {
            "description": "Identificador único de la política",
            "type": "string"
          },
          "policy_name": {
            "description": "Nombre de la política",
            "type": "string"
          },
          "result": {
            "description": "Resultado de la evaluación",
            "type": "string",
            "enum": [
              "met",
              "not_met",
              "not_applicable"
            ]
          },
          "explanation": {
            "description": "Explicación generada por LLM sobre la evaluación",
            "type": "string"
          },
          "evaluated_at": {
            "description": "Cuándo se evaluó esta política",
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "OffsetPagination": {
        "type": "object",
        "description": "Filters are applied to each request independently. Changing filters while paginating may result in gaps or overlaps in the result set. For consistent results, maintain the same filters throughout pagination.",
        "properties": {
          "has_next": {
            "type": "boolean",
            "description": "Boolean describing if there are more items to fetch"
          },
          "has_previous": {
            "type": "boolean",
            "description": "Boolean describing if there are previous items to fetch"
          },
          "next_page": {
            "type": "integer",
            "description": "Page Index to the next page to return. Can be null if there are no more pages."
          },
          "previous_page": {
            "type": "integer",
            "description": "Page Index to the previous page to return. Can be null if there are no previous pages."
          }
        }
      }
    },
    "securitySchemes": {
      "apiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "Authorization",
        "description": "Add `api-key YOUR_API_SECRET_KEY` as the value of the `Authorization` header."
      }
    }
  }
}