{
  "openapi": "3.0.3",
  "info": {
    "title": "IAlgo+ CRM — API v1",
    "version": "1.0.0",
    "description": "API REST del CRM IAlgo+. El espacio (empresa) al que apunta lo determina el token de API. Autenticación por cabecera Bearer o X-Api-Key. La clave real NO va en este documento: usa TU_CLAVE y guarda el valor en deploy/.env del servidor."
  },
  "servers": [
    {
      "url": "https://ialgomas.io/api/v1",
      "description": "API v1 accesible desde el dominio principal (proxy hacia el CRM)."
    },
    {
      "url": "https://crm.ialgomas.io/api/v1",
      "description": "API v1 canónica del CRM (multiempresa)."
    }
  ],
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ],
  "tags": [
    {
      "name": "leads",
      "description": "Leads (oportunidades entrantes sin cualificar)"
    },
    {
      "name": "contacts",
      "description": "Contactos (personas)"
    },
    {
      "name": "accounts",
      "description": "Empresas / cuentas"
    },
    {
      "name": "opportunities",
      "description": "Oportunidades de venta"
    }
  ],
  "paths": {
    "/leads": {
      "get": {
        "tags": [
          "leads"
        ],
        "summary": "Listar leads",
        "operationId": "listLeads",
        "parameters": [
          {
            "$ref": "#/components/parameters/perPage"
          },
          {
            "$ref": "#/components/parameters/page"
          }
        ],
        "responses": {
          "200": {
            "description": "Listado paginado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedLeads"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      },
      "post": {
        "tags": [
          "leads"
        ],
        "summary": "Crear un lead",
        "operationId": "createLead",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LeadInput"
              },
              "example": {
                "title": "Interés en producto X",
                "contact_name": "Ana Pérez",
                "company_name": "Acme S.L.",
                "email": "ana@acme.com",
                "phone": "600123123",
                "value": 1500,
                "status": "nuevo",
                "source": "web",
                "notes": "Mensaje del cliente"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Lead creado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Lead"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          }
        }
      }
    },
    "/leads/{id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/id"
        }
      ],
      "get": {
        "tags": [
          "leads"
        ],
        "summary": "Ver un lead",
        "operationId": "getLead",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Lead"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      },
      "put": {
        "tags": [
          "leads"
        ],
        "summary": "Actualizar un lead",
        "operationId": "updateLead",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LeadInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Actualizado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Lead"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      },
      "delete": {
        "tags": [
          "leads"
        ],
        "summary": "Borrar un lead",
        "operationId": "deleteLead",
        "responses": {
          "200": {
            "description": "Borrado"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/contacts": {
      "get": {
        "tags": [
          "contacts"
        ],
        "summary": "Listar contactos",
        "operationId": "listContacts",
        "parameters": [
          {
            "$ref": "#/components/parameters/perPage"
          },
          {
            "$ref": "#/components/parameters/page"
          }
        ],
        "responses": {
          "200": {
            "description": "Listado paginado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedContacts"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      },
      "post": {
        "tags": [
          "contacts"
        ],
        "summary": "Crear un contacto",
        "operationId": "createContact",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContactInput"
              },
              "example": {
                "first_name": "Ana",
                "last_name": "Pérez",
                "email": "ana@acme.com",
                "phone": "600123123"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Contacto creado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Contact"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          }
        }
      }
    },
    "/contacts/{id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/id"
        }
      ],
      "get": {
        "tags": [
          "contacts"
        ],
        "summary": "Ver un contacto",
        "operationId": "getContact",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Contact"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      },
      "put": {
        "tags": [
          "contacts"
        ],
        "summary": "Actualizar un contacto",
        "operationId": "updateContact",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContactInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Actualizado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Contact"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      },
      "delete": {
        "tags": [
          "contacts"
        ],
        "summary": "Borrar un contacto",
        "operationId": "deleteContact",
        "responses": {
          "200": {
            "description": "Borrado"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/accounts": {
      "get": {
        "tags": [
          "accounts"
        ],
        "summary": "Listar empresas",
        "operationId": "listAccounts",
        "parameters": [
          {
            "$ref": "#/components/parameters/perPage"
          },
          {
            "$ref": "#/components/parameters/page"
          }
        ],
        "responses": {
          "200": {
            "description": "Listado paginado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedAccounts"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      },
      "post": {
        "tags": [
          "accounts"
        ],
        "summary": "Crear una empresa",
        "operationId": "createAccount",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AccountInput"
              },
              "example": {
                "name": "Acme S.L.",
                "email": "info@acme.com",
                "phone": "930000000",
                "industry": "Tecnología",
                "website": "https://acme.com"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Empresa creada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Account"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          }
        }
      }
    },
    "/accounts/{id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/id"
        }
      ],
      "get": {
        "tags": [
          "accounts"
        ],
        "summary": "Ver una empresa",
        "operationId": "getAccount",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Account"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      },
      "put": {
        "tags": [
          "accounts"
        ],
        "summary": "Actualizar una empresa",
        "operationId": "updateAccount",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AccountInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Actualizado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Account"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      },
      "delete": {
        "tags": [
          "accounts"
        ],
        "summary": "Borrar una empresa",
        "operationId": "deleteAccount",
        "responses": {
          "200": {
            "description": "Borrado"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/opportunities": {
      "get": {
        "tags": [
          "opportunities"
        ],
        "summary": "Listar oportunidades",
        "operationId": "listOpportunities",
        "parameters": [
          {
            "$ref": "#/components/parameters/perPage"
          },
          {
            "$ref": "#/components/parameters/page"
          }
        ],
        "responses": {
          "200": {
            "description": "Listado paginado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedOpportunities"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      },
      "post": {
        "tags": [
          "opportunities"
        ],
        "summary": "Crear una oportunidad",
        "operationId": "createOpportunity",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OpportunityInput"
              },
              "example": {
                "title": "Proyecto Acme",
                "account_id": 12,
                "contact_id": 34,
                "stage": "prospeccion",
                "amount": 5000
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Oportunidad creada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Opportunity"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          }
        }
      }
    },
    "/opportunities/{id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/id"
        }
      ],
      "get": {
        "tags": [
          "opportunities"
        ],
        "summary": "Ver una oportunidad",
        "operationId": "getOpportunity",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Opportunity"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      },
      "put": {
        "tags": [
          "opportunities"
        ],
        "summary": "Actualizar una oportunidad",
        "operationId": "updateOpportunity",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OpportunityInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Actualizado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Opportunity"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      },
      "delete": {
        "tags": [
          "opportunities"
        ],
        "summary": "Borrar una oportunidad",
        "operationId": "deleteOpportunity",
        "responses": {
          "200": {
            "description": "Borrado"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Cabecera: Authorization: Bearer TU_CLAVE"
      },
      "apiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Api-Key",
        "description": "Alternativa: X-Api-Key: TU_CLAVE"
      }
    },
    "parameters": {
      "id": {
        "name": "id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "integer"
        }
      },
      "perPage": {
        "name": "per_page",
        "in": "query",
        "required": false,
        "schema": {
          "type": "integer",
          "default": 50,
          "minimum": 1,
          "maximum": 200
        }
      },
      "page": {
        "name": "page",
        "in": "query",
        "required": false,
        "schema": {
          "type": "integer",
          "default": 1,
          "minimum": 1
        }
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Falta el token o es inválido",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "Token inválido o desactivado."
            }
          }
        }
      },
      "NotFound": {
        "description": "No encontrado",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "No encontrado"
            }
          }
        }
      },
      "ValidationError": {
        "description": "Datos inválidos",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          }
        }
      },
      "Pagination": {
        "type": "object",
        "properties": {
          "current_page": {
            "type": "integer",
            "example": 1
          },
          "per_page": {
            "type": "integer",
            "example": 50
          },
          "total": {
            "type": "integer",
            "example": 137
          },
          "last_page": {
            "type": "integer",
            "example": 3
          }
        }
      },
      "Lead": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "readOnly": true
          },
          "title": {
            "type": "string"
          },
          "contact_name": {
            "type": "string",
            "nullable": true
          },
          "company_name": {
            "type": "string",
            "nullable": true
          },
          "email": {
            "type": "string",
            "format": "email",
            "nullable": true
          },
          "phone": {
            "type": "string",
            "nullable": true
          },
          "value": {
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "status": {
            "type": "string",
            "enum": [
              "nuevo",
              "contactado",
              "cualificado",
              "negociacion",
              "ganado",
              "perdido"
            ]
          },
          "source": {
            "type": "string",
            "enum": [
              "web",
              "whatsapp",
              "recomendacion",
              "llamada",
              "email",
              "otro"
            ],
            "nullable": true
          },
          "notes": {
            "type": "string",
            "nullable": true
          },
          "owner_id": {
            "type": "integer",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          }
        }
      },
      "LeadInput": {
        "type": "object",
        "required": [
          "title"
        ],
        "properties": {
          "title": {
            "type": "string",
            "description": "Título de la ficha (único campo obligatorio)"
          },
          "contact_name": {
            "type": "string"
          },
          "company_name": {
            "type": "string"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "phone": {
            "type": "string"
          },
          "value": {
            "type": "number",
            "format": "float"
          },
          "status": {
            "type": "string",
            "enum": [
              "nuevo",
              "contactado",
              "cualificado",
              "negociacion",
              "ganado",
              "perdido"
            ],
            "default": "nuevo"
          },
          "source": {
            "type": "string",
            "enum": [
              "web",
              "whatsapp",
              "recomendacion",
              "llamada",
              "email",
              "otro"
            ]
          },
          "notes": {
            "type": "string"
          }
        }
      },
      "Contact": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "readOnly": true
          },
          "first_name": {
            "type": "string"
          },
          "last_name": {
            "type": "string",
            "nullable": true
          },
          "email": {
            "type": "string",
            "format": "email",
            "nullable": true
          },
          "phone": {
            "type": "string",
            "nullable": true
          },
          "account_id": {
            "type": "integer",
            "nullable": true,
            "description": "ID de la empresa a la que pertenece"
          },
          "owner_id": {
            "type": "integer",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          }
        }
      },
      "ContactInput": {
        "type": "object",
        "required": [
          "first_name"
        ],
        "properties": {
          "first_name": {
            "type": "string"
          },
          "last_name": {
            "type": "string"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "phone": {
            "type": "string"
          },
          "account_id": {
            "type": "integer"
          }
        }
      },
      "Account": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "readOnly": true
          },
          "name": {
            "type": "string"
          },
          "email": {
            "type": "string",
            "format": "email",
            "nullable": true
          },
          "phone": {
            "type": "string",
            "nullable": true
          },
          "industry": {
            "type": "string",
            "nullable": true
          },
          "website": {
            "type": "string",
            "nullable": true
          },
          "notes": {
            "type": "string",
            "nullable": true
          },
          "owner_id": {
            "type": "integer",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          }
        }
      },
      "AccountInput": {
        "type": "object",
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "phone": {
            "type": "string"
          },
          "industry": {
            "type": "string"
          },
          "website": {
            "type": "string"
          },
          "notes": {
            "type": "string"
          }
        }
      },
      "Opportunity": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "readOnly": true
          },
          "title": {
            "type": "string"
          },
          "account_id": {
            "type": "integer",
            "nullable": true
          },
          "contact_id": {
            "type": "integer",
            "nullable": true
          },
          "stage": {
            "type": "string",
            "description": "Etapa del embudo (p.ej. prospeccion, propuesta, negociacion, ganada, perdida)"
          },
          "amount": {
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "probability": {
            "type": "integer",
            "nullable": true
          },
          "expected_close_date": {
            "type": "string",
            "format": "date",
            "nullable": true
          },
          "notes": {
            "type": "string",
            "nullable": true
          },
          "owner_id": {
            "type": "integer",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          }
        }
      },
      "OpportunityInput": {
        "type": "object",
        "required": [
          "title"
        ],
        "properties": {
          "title": {
            "type": "string"
          },
          "account_id": {
            "type": "integer"
          },
          "contact_id": {
            "type": "integer"
          },
          "stage": {
            "type": "string"
          },
          "amount": {
            "type": "number",
            "format": "float"
          },
          "probability": {
            "type": "integer"
          },
          "expected_close_date": {
            "type": "string",
            "format": "date"
          },
          "notes": {
            "type": "string"
          }
        }
      },
      "PaginatedLeads": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Pagination"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Lead"
                }
              }
            }
          }
        ]
      },
      "PaginatedContacts": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Pagination"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Contact"
                }
              }
            }
          }
        ]
      },
      "PaginatedAccounts": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Pagination"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Account"
                }
              }
            }
          }
        ]
      },
      "PaginatedOpportunities": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Pagination"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Opportunity"
                }
              }
            }
          }
        ]
      }
    }
  }
}