openapi: 3.0.3
info:
  title: UNO Collective — Agent API
  description: |
    API pública de UNO Collective para agentes de IA y chatbots.

    ## Estado actual (v0.3 — junio 2026)

    Esta spec describe los **4 endpoints del piloto v0** (ADR 0003).
    Están **planeados** pero **no todos implementados todavía**. El estado
    real de cada uno está marcado en la descripción y en `x-status`.

    - `/api/discovery` — **planeado** (siguiente en implementar)
    - `/api/quote` — **planeado**
    - `/api/transaction` — **planeado**
    - `/api/status/{project_id}` — **planeado**

    Mientras tanto, el flujo v0 es:
    - **Pedido de prueba / cotización inicial:** formulario en `https://www.unocollective.com/#contacto`
      (humano responde < 24h hábiles).
    - **Catálogo estructurado:** `GET /catalog.json` (ya activo, 144 capacidades).
    - **Descripción legible:** `GET /llms.txt` (ya activo).

    ## Política de contratación agentic

    Ver `https://www.unocollective.com/llms.txt` sección "Política de
    contratación agentic" para el detalle de los 4 modos progresivos.

    ## Modos de cierre

    | Modo | Quién cierra | Cuándo aplica |
    |---|---|---|
    | 1. Pedido de prueba | humano | siempre, sin validaciones |
    | 2. Cotización | humano | briefs estructurados |
    | 3. Plan fijo (auto) | auto | Content/UGC, Especialidades, B2B, Agent Marketing |
    | 4. Custom (humano en loop) | humano | retainer > USD 3.000/mes, contrato + factura + transferencia |

  version: 0.3.0
  contact:
    name: UNO Collective
    email: hello@unocollective.com
    url: https://www.unocollective.com
  license:
    name: UNO Collective internal
    url: https://www.unocollective.com/

servers:
  - url: https://www.unocollective.com
    description: Producción
  - url: https://test-unoco.vercel.app
    description: Staging (Vercel preview)

tags:
  - name: discovery
    description: Información de UNO Collective para agentes (servicios, planes, qualifiers)
  - name: quote
    description: Cotización — el agente envía un brief, recibe plan + precio
  - name: transaction
    description: Contratación — confirmación de cotización + pago + apertura de proyecto
  - name: status
    description: Estado del proyecto + acciones (comment / approve / revision)

paths:
  /api/discovery:
    get:
      tags: [discovery]
      summary: Discovery de UNO Collective
      description: |
        Devuelve información estructurada sobre UNO Collective: servicios,
        planes, qualifiers, links a OpenAPI y `/llms.txt`.

        Pensado para que un agente haga **una sola request** y tenga todo
        lo que necesita para evaluar si hay match con un cliente.

        **Estado:** planeado (H1, sin implementar todavía).
      operationId: getDiscovery
      x-status: planned
      responses:
        '200':
          description: Discovery exitoso
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DiscoveryResponse'
              examples:
                example:
                  value:
                    name: UNO Collective
                    description: Agencia de marketing digital LATAM & USA. Agent-ready.
                    services_root: 7
                    plans_count: 7
                    total_capabilities: 144
                    geographies: [Argentina, México, "USA (hispano)", LATAM]
                    languages: ["Español (AR/MX/NEUTRO)", "Inglés (ES→EN)"]
                    links:
                      llms_txt: https://www.unocollective.com/llms.txt
                      catalog_json: https://www.unocollective.com/catalog.json
                      openapi: https://www.unocollective.com/api/openapi.yaml
                      agentic_landing: https://www.unocollective.com/agentic
                    match_signals:
                      positive:
                        - "B2C lead generation"
                        - "Meta Ads o Google Ads foco"
                        - "Inversión publicitaria > USD 10K/mes"
                        - "Geografía: AR / MX / USA hispano / LATAM"
                        - "Marca con trayectoria que precisa restyling total"
                        - "Empresa arrancando"
                        - "Necesidad de centralizar ads + contenido + reporting"
                      negative:
                        - "Prospección outbound B2B"
                        - "Headhunting / búsqueda de ejecutivos"
                        - "Eventos presenciales"
                        - "Diseño de interiores o arquitectura"
                        - "Servicios legales o contables"
        '501':
          description: No implementado todavía
          content:
            application/json:
              example:
                error: not_implemented
                message: "Discovery endpoint planeado para H1. Mientras tanto usar /llms.txt y /catalog.json."

  /api/quote:
    post:
      tags: [quote]
      summary: Solicitar cotización
      description: |
        El agente envía un brief estructurado. UNO devuelve una cotización
        con plan recomendado + precio + próximos pasos.

        **Estado:** planeado. Mientras tanto, enviar el brief por
        `https://www.unocollective.com/#contacto` (humano responde < 24h hábiles).
      operationId: createQuote
      x-status: planned
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/QuoteRequest'
            example:
              agent_id: claude-by-joaquin
              client:
                company: Acme Corp
                country: MX
                contact_email: juan@acme.com
              brief:
                need: "Generación de leads B2C vía Meta Ads"
                monthly_budget_usd: 12000
                geographies: [MX, USA]
                languages: ["Español (MX)"]
                timeline: "< 30 días"
              preferences:
                mode: "fixed_plan"  # o "custom"
                needs_human_approval: true
      responses:
        '200':
          description: Cotización creada (humano responderá < 24h)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QuoteResponse'
        '501':
          description: No implementado todavía

  /api/transaction:
    post:
      tags: [transaction]
      summary: Confirmar cotización y abrir proyecto
      description: |
        Confirma una cotización y abre un proyecto en UNO.

        **Modo `fixed_plan`:** auto, sin humano. Se abre ticket en ClickUp y se
        devuelve `project_id` + link de pago. Pago v0: link manual por email.
        Pago v1: x402 (USA) y/o MercadoPago (LATAM).

        **Modo `custom`:** humano en el loop. Se genera contrato + factura.
        El pago lo hace la **empresa cliente por transferencia bancaria** en
        la fecha acordada (no se paga desde wallet de agentes).

        **Estado:** planeado.
      operationId: createTransaction
      x-status: planned
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TransactionRequest'
            example:
              quote_id: q_abc123
              mode: fixed_plan
              payment_method: email_link  # o "x402" (v1), "transfer" (custom)
      responses:
        '200':
          description: Transacción creada
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionResponse'
        '501':
          description: No implementado todavía

  /api/status/{project_id}:
    get:
      tags: [status]
      summary: Estado del proyecto
      description: |
        Devuelve el estado actual del proyecto, milestones, deliverables, etc.

        **Estado:** planeado. Una vez activo, también habrá endpoints
        de acción: `/api/status/{project_id}/comment`, `/approve`, `/revision`.
      operationId: getProjectStatus
      x-status: planned
      parameters:
        - name: project_id
          in: path
          required: true
          schema:
            type: string
          example: proj_abc123
      responses:
        '200':
          description: Estado del proyecto
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProjectStatus'
        '404':
          description: Proyecto no encontrado
        '501':
          description: No implementado todavía

components:
  schemas:
    DiscoveryResponse:
      type: object
      required: [name, description, services_root, plans_count, links]
      properties:
        name: { type: string }
        description: { type: string }
        services_root: { type: integer, description: "Disciplinas raíz (7)" }
        plans_count: { type: integer }
        total_capabilities: { type: integer, description: "Capacidades del catálogo (144)" }
        geographies:
          type: array
          items: { type: string }
        languages:
          type: array
          items: { type: string }
        links:
          type: object
          properties:
            llms_txt: { type: string, format: uri }
            catalog_json: { type: string, format: uri }
            openapi: { type: string, format: uri }
            agentic_landing: { type: string, format: uri }
        match_signals:
          type: object
          properties:
            positive:
              type: array
              items: { type: string }
            negative:
              type: array
              items: { type: string }

    QuoteRequest:
      type: object
      required: [agent_id, client, brief]
      properties:
        agent_id: { type: string, description: "Identificador del agente que pide" }
        client:
          type: object
          required: [country]
          properties:
            company: { type: string }
            country: { type: string, description: "ISO 3166-1 alpha-2 o nombre libre" }
            contact_email: { type: string, format: email }
        brief:
          type: object
          required: [need]
          properties:
            need: { type: string, description: "Qué necesita el cliente" }
            monthly_budget_usd: { type: number }
            geographies:
              type: array
              items: { type: string }
            languages:
              type: array
              items: { type: string }
            timeline: { type: string, description: "Ej: '< 30 días', '1-3 meses'" }
        preferences:
          type: object
          properties:
            mode:
              type: string
              enum: [fixed_plan, custom]
              default: fixed_plan
            needs_human_approval: { type: boolean, default: true }

    QuoteResponse:
      type: object
      properties:
        quote_id: { type: string }
        recommended_plan:
          type: object
          properties:
            id: { type: string }
            name: { type: string }
            from_usd: { type: number }
        estimated_price_usd: { type: number }
        sla_response_hours: { type: integer, description: "SLA objetivo de respuesta humana" }
        next_steps:
          type: array
          items: { type: string }
        notes: { type: string }

    TransactionRequest:
      type: object
      required: [quote_id, mode]
      properties:
        quote_id: { type: string }
        mode:
          type: string
          enum: [fixed_plan, custom]
        payment_method:
          type: string
          enum: [email_link, x402, transfer]
          description: "email_link (v0), x402 (v1 USA), transfer (custom, factura)"

    TransactionResponse:
      type: object
      properties:
        project_id: { type: string }
        status_url: { type: string, format: uri }
        payment:
          type: object
          properties:
            method: { type: string }
            link: { type: string, format: uri, nullable: true }
            due_date: { type: string, format: date, nullable: true }
        clickup_ticket: { type: string }

    ProjectStatus:
      type: object
      properties:
        project_id: { type: string }
        status:
          type: string
          enum: [pending_payment, in_progress, awaiting_approval, revision_requested, completed, cancelled]
        milestones:
          type: array
          items:
            type: object
            properties:
              name: { type: string }
              status: { type: string }
              completed_at: { type: string, format: date-time, nullable: true }
        deliverables:
          type: array
          items: { type: object }
        next_action:
          type: object
          properties:
            required: { type: boolean }
            description: { type: string }
            endpoint: { type: string, nullable: true }
