openapi: 3.0.0
info:
  title: Coleccion de API KYB MX
  description: |
    La Colección de API KYB MX proporciona puntos finales para crear y gestionar verificaciones de empresas en México. La verificación de empresas implica validar la información proporcionada por un cliente comercial, incluyendo documentos y fuentes de datos, para asegurar su legitimidad y precisión.

    Cada verificación de empresa puede incluir múltiples ítems, como Actas Constitutivas, Constancias de Situación Fiscal, Identificaciones Personales y Comprobantes de Domicilio. Trebol maneja automáticamente la clasificación de documentos, lo que te permite enviar todos los documentos requeridos como URLs descargables (por ejemplo, URLs prefirmadas de AWS o GCP).

    **Autenticación**: 
    La API utiliza una clave API para la autenticación, pasada en el encabezado `x-api-key`. Para obtener una clave API, por favor [contáctanos](mailto:sales@gotrebol.com).

  version: 1.0.0

servers:
  - url: https://api.gotrebol.com
  - url: http://{{trebol_api_base_url}}

tags:
  - name: Creacion de Verificacion
    description: Endpoints para crear nuevas verificaciones.
  - name: Leer información de la empresa
    description: Endpoints v2 para obtener información detallada de empresas y verificaciones.
  - name: Leer por Etiqueta
    description: Endpoints para obtener información detallada sobre empresas mediante etiquetas.
  - name: Leer por ID de Verificacion
    description: Endpoints para obtener información detallada sobre verificaciones mediante ID.
  - name: Gestión de IPs Permitidas
    description: Endpoints para gestionar la lista de IPs permitidas (whitelist) para la cuenta del cliente.
  - name: Gestión de API Keys
    description: Endpoints para crear, listar y eliminar API keys de la cuenta del usuario.
  - name: Gestion de item Ids
    description: Endpoints para gestionar items de verificaciones.
  - name: Invalidar un documento
    description: Endpoints para invalidar documentos de verificaciones.
  - name: Labels de Verificacion
    description: Endpoints para gestionar labels de verificaciones.
  - name: Actualizar personas clave de una verificacion
    description: Endpoints para actualizar personas clave de verificaciones.
  - name: Agregar items a una verificacion
    description: Endpoints para agregar items a verificaciones existentes.
  - name: Estado de validacion de documentos
    description: Endpoints para obtener el estado de validación de documentos.
  - name: Gestión de Flujos de Cuenta
    description: Endpoints para gestionar flujos de cuenta.
  - name: Gestión de Webhooks
    description: Endpoints para crear, listar, actualizar y eliminar webhooks de la cuenta.
  - name: Gestión de Política de Retención
    description: Endpoints para gestionar la política de retención de datos de la cuenta.
  - name: Exportación de Verificaciones
    description: Endpoints para exportar datos de verificaciones a documentos personalizados.
  - name: Leer información de la empresa v1
    description: Endpoints v1 (legacy) para obtener información detallada de empresas y verificaciones. Te recomendamos migrar a los endpoints v2.
  - name: Tipos de Ítem Personalizados
    description: Endpoints para crear y gestionar tipos de ítem personalizados con procesos configurables de clasificación, validación y extracción.
  - name: Síntesis de Dictamen
    description: Endpoints para ejecutar bajo demanda la Síntesis de Dictamen (`findings`) de una verificación.

paths:
  /verifications:
    post:
      operationId: crearNuevaVerificacion
      tags:
        - Creacion de Verificacion
      summary: Crear una nueva verificación
      description: |
        Inicia una nueva verificación con los documentos especificados.

        **Nota:** Este endpoint permite crear verificaciones de empresas con documentos y configuraciones personalizadas.

        **RFC de prueba:** con `tax_id` igual a `TRB010101OK1`, `TRB010101NF1`, `TRB010101ER1`, `TRB010101DV1` o `TRB010101RF1`, la verificación se resuelve con una respuesta fija de KYB México, sin consultar fuentes externas y sin cobro. Trébol reemplaza los items enviados por los del escenario. Ver [RFC de prueba](/guia-devs/pruebas/rfc-de-prueba).
      security:
        - ApiKeyAuth: []
      requestBody:
        description: |
          Hay dos formas de crear una verificacion, usando un flujo predefinido, el cual ya contiene todos los items y configuraciones necesarias o bien 
          pasando un array de items a verificar, la cual permite crear una verificacion con items personalizados, sin un flujo predefinido.
        content:
          application/json:
            schema:
              oneOf:
                - $ref: "#/components/schemas/VerificationWithFlowId"
                - $ref: "#/components/schemas/VerificationWithItems"
            examples:
              ConFlowId:
                summary: Usando flow_id
                value:
                  country: "mx"
                  tag: "etiqueta"
                  flow_id: "some-flow-id"
                  friendly_name: "Empresa ACME S.A. de C.V."
                  metadata:
                    some: "value"
                  key_people:
                    - names: "John Doe"
                      scope: ["powers"]
              ConItems:
                summary: Usando items
                value:
                  country: "mx"
                  tag: "etiqueta"
                  friendly_name: "Juan Pérez López"
                  items:
                    - type: "generic"
                      options:
                        file_url: "https://www.somepresignedURL.com/withDownloadableFile"
                        client_item_type: "ac_mx"
                    - type: "generic"
                      options:
                        file_url: "https://www.somepresignedURL.com/withDownloadableFile"
                        people_scope: ["powers"]
                        client_item_type: "person_id"
                  metadata:
                    some: "value"
                  key_people:
                    - names: "John Doe"
                      scope: ["powers"]
              ConTipoItemPersonalizado:
                summary: Usando un tipo de ítem personalizado
                description: |
                  Cuando tienes un tipo de ítem personalizado creado vía `/v2/custom-item-types`,
                  usa su `name` como valor de `type` en el ítem.
                  Consulta la guía [Tipos de ítem personalizados](/producto/guias/tipos-de-item-personalizados).
                value:
                  country: "mx"
                  tag: "empresa-ejemplo-001"
                  friendly_name: "Empresa ACME S.A. de C.V."
                  items:
                    - type: "cit_contrato_arrendamiento"
                      options:
                        file_url: "https://www.somepresignedURL.com/withDownloadableFile"
              RfcDePrueba:
                summary: Usando un RFC de prueba
                description: |
                  Crea una verificación de prueba del escenario A (todo encontrado). Usa `TRB010101NF1` para el escenario B (no encontrado), `TRB010101ER1` para el C (error técnico), `TRB010101DV1` para el D (validación de documentos) o `TRB010101RF1` para el E (consulta de RFC).
                  Los items se validan y después se reemplazan por los 22 (A), 17 (B y C) o 4 (D y E) del escenario; los archivos enviados se ignoran.
                  Consulta la guía [RFC de prueba](/guia-devs/pruebas/rfc-de-prueba).
                value:
                  country: "mx"
                  tag: "prueba-escenario-a"
                  tax_id: "TRB010101OK1"
                  items:
                    - type: "ac_mx"
                      options:
                        file_url: "https://example.com/acta.pdf"
      responses:
        "201":
          description: Verificación creada exitosamente.
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                    description: ID de la verificación creada.
                    example: "c8dc41fc-c477-404e-aff7-b9074f86d6d1"
                  status:
                    type: string
                    description: Estado actual de la verificación.
                    example: "pending"
                  account_id:
                    type: string
                    format: uuid
                    description: ID de la cuenta asociada.
                    example: "99999999-9999-9999-9999-999999999999"
                  created_at:
                    type: string
                    format: date-time
                    description: Fecha y hora de creación de la verificación.
                    example: "2025-04-28T20:10:06.840Z"
                  updated_at:
                    type: string
                    format: date-time
                    description: Fecha y hora de última actualización de la verificación.
                    example: "2025-04-28T20:10:06.840Z"
                  flow_id:
                    type: string
                    description: Identificador del flujo de verificación utilizado.
                    example: "documents-v2"
                  documents_status:
                    type: string
                    enum:
                      [
                        pending_upload,
                        partial_upload,
                        pending_external,
                        full_upload,
                      ]
                    description: Estado de la colección de documentos.
                    example: "pending_upload"
                  onboarding_url:
                    type: string
                    format: uri
                    description: Link de onboarding para el cliente. Usa el dominio default de Trébol, o el dominio personalizado de la cuenta cuando está verificado (ver "Personalizar el widget").
                    example: "https://onboarding.gotrebol.com/verification/c8dc41fc-c477-404e-aff7-b9074f86d6d1/docs-v2?accessToken=accesstokenid32432434&country=mx&client=99999999-9999-9999-9999-999999999999"
                  details_url:
                    type: string
                    format: uri
                    description: Link al reporte de la verificación.
                    example: "https://app.gotrebol.com/verifications/c8dc41fc-c477-404e-aff7-b9074f86d6d1"
                  access_token:
                    type: string
                    description: Token de acceso JWT para la sesión de verificación.
                    example: "eyJhbGciOiJIUzI1NiJ9..."
                  items:
                    type: array
                    description: Lista de ítems/documentos a verificar.
                    items:
                      type: object
                      properties:
                        id:
                          type: integer
                          description: ID del ítem/documento.
                          example: 25440
                        item_status:
                          type: string
                          description: Estado del ítem/documento.
                          example: "pending"
                          enum: [pending, complete]
                        item_type:
                          type: string
                          description: Tipo de ítem/documento.
                          example: "ubos"
                        item_internal_status:
                          type: string
                          description: Estado interno del ítem/documento.
                          example: "pending_validation"
                          nullable: true
                        item_value:
                          type: object
                          description: Valores especificos del ítem/documento.
                        validation_result:
                          type: object
                          description: Resultado de las validaciones del ítem/documento.
                          nullable: true
                        item_scope:
                          type: string
                          description: Alcance del ítem/documento.
                          enum: [basic, advanced]
                          example: "basic"
                        item_options:
                          type: object
                          description: Opciones adicionales del ítem/documento que afectan al proceso interno del mismo.
                          properties:
                            upload_url:
                              type: string
                              format: uri
                              description: URL firmada temporal para subir el archivo del item mediante PUT antes de confirmar con options.uploaded_file.
                            is_optional:
                              type: boolean
                              description: Indica si el ítem/documento es opcional.
                              example: true
                          nullable: true
                  tag:
                    type: string
                    description: Etiqueta identificadora única del creador de la verificación.
                    example: "33332-34-22"
                  email:
                    type: string
                    format: email
                    description: Correo electrónico asociado a la verificación.
                    example: "johndoe@mail.com"
                  country:
                    type: string
                    description: Código de país ISO 3166-1 alfa-2.
                    example: "mx"
                  tax_id:
                    type: string
                    description: RFC o número de identificación fiscal.
                    example: "SAG160927GIA"
                  business_name:
                    type: string
                    description: Nombre comercial de la empresa extraído automáticamente de los documentos.
                    nullable: true
                    example: "Trebol OPCO SAS"
                  friendly_name:
                    type: string
                    nullable: true
                    description: >
                      Nombre descriptivo asignado por el usuario al crear la verificación. Permite
                      identificar fácilmente la empresa o persona asociada a la verificación.
                    example: "Empresa ACME S.A. de C.V."
                  options:
                    type: object
                    description: Objeto reservado para opciones adicionales.
                  created_by:
                    type: string
                    description: ID del usuario/cliente que creó la verificación.
                    example: "99999999-9999-9999-9999-999999999999"
                  onboarding_terms_and_conditions:
                    type: string
                    description: Lista de terminos y condiciones de onboarding aprobados por el cliente y asociados a la verificación.
                    nullable: true
        "208":
          description: |
            Verificación duplicada detectada. Se retorna cuando se intenta crear una verificación que ya existe 
            en el sistema para la misma empresa y flujo.

            **Condiciones para recibir este código:**
            - El parámetro `verify_duplicate_verification` debe ser `true`
            - Se debe proporcionar un `tax_id` (RFC/NIT) válido
            - Se debe proporcionar un `flow_id` válido
            - Ya existe una verificación activa con el mismo `tax_id`, `account_id` y `flow_id`

            **Comportamiento:**
            - Se envía automáticamente un enlace de acceso al email del creador original
            - Se retorna información básica sobre la verificación existente (con email enmascarado)
            - No se crea una nueva verificación
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    description: Siempre será `false` para indicar que no se creó una nueva verificación
                    example: false
                  data:
                    type: object
                    description: Información sobre la verificación existente
                    properties:
                      creator_email:
                        type: string
                        description: |
                          Email del creador de la verificación original, enmascarado por privacidad.
                          Formato: primer_carácter + asteriscos + último_carácter + @dominio
                          Ejemplo: "john.doe@example.com" → "j**********e@example.com"
                        example: "j***@domain.com"
                      business_name:
                        type: string
                        description: Nombre comercial de la empresa de la verificación existente
                        example: "Trebol OPCO"
                    required:
                      - creator_email
                      - business_name
              examples:
                DuplicateVerification:
                  summary: Verificación duplicada detectada
                  description: |
                    Respuesta cuando se intenta crear una verificación que ya existe para la misma empresa y flujo.
                    El sistema automáticamente envía un enlace de acceso al creador original.
                  value:
                    success: false
                    data:
                      creator_email: "j***@trebol.com"
                      business_name: "Empresa Ejemplo S.A. de C.V."
        "400":
          description: |
            Solicitud inválida. Posibles causas:
            - Un ítem referencia un tipo de ítem personalizado que no existe o fue eliminado.
            - Otros errores de validación del request.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "422":
          description: |
            Un ítem referencia un tipo de ítem personalizado archivado.
            El tipo tiene `status = 'archived'`.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "500":
          $ref: "#/components/responses/InternalServerError"
    get:
      operationId: listarVerificaciones
      tags:
        - Leer información de la empresa
      summary: Listar verificaciones de la cuenta
      description: |
        Retorna las verificaciones asociadas a la cuenta con paginación basada en tokens.
        El tamaño de página por defecto es 10 y el máximo permitido es 20.
      security:
        - ApiKeyAuth: []
      parameters:
        - name: status
          in: query
          required: false
          description: Filtra por el estado de la verificación.
          schema:
            type: string
            enum: [pending, finished, error, pending_validation]
        - name: page_size
          in: query
          required: false
          description: |
            Cantidad de verificaciones por página. Valor por defecto: `10`.
            Debe ser un entero positivo; valores no enteros o menores o iguales a `0` resultan en `400 Bad Request`.
            Valores mayores a `20` se ajustan automáticamente al máximo permitido (`20`).
          schema:
            type: integer
            minimum: 1
            default: 10
        - name: next
          in: query
          required: false
          description: Token de paginación para obtener la siguiente página de resultados.
          schema:
            type: string
      responses:
        "200":
          description: Lista de verificaciones obtenida exitosamente.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/PublicVerification"
                    description: Lista de verificaciones.
                  next:
                    type: string
                    description: Token para obtener la siguiente página de resultados (presente solo si hay más páginas).
                    nullable: true
              examples:
                Success:
                  summary: Lista de verificaciones obtenida exitosamente
                  value:
                    data:
                      - id: "c8dc41fc-c477-404e-aff7-b9074f86d6d1"
                        account_id: "99999999-9999-9999-9999-999999999999"
                        status: "pending"
                        created_at: "2025-04-28T20:10:06.840Z"
                        updated_at: "2025-04-28T20:10:06.840Z"
                        tag: "etiqueta"
                        tax_id: "SAG160927GIA"
                        business_name: "Trebol OPCO"
                        friendly_name: "Empresa ACME S.A. de C.V."
                        flow_id: "documents-v2"
                        details_url: "https://app.gotrebol.com/verifications/c8dc41fc-c477-404e-aff7-b9074f86d6d1"
                        onboarding_url: "https://onboarding.gotrebol.com/verification/c8dc41fc..."
                        items:
                          - id: 25440
                            item_status: "pending"
                            item_type: "csf_mx"
                            item_value: {}
                    next: "eyJjcmVhdGVkQXQiOiIyMDI1LTA0LTI4VDIwOjEwOjA2Ljg0MFoiLCJpZCI6ImM4ZGM0MWZjLWM0NzctNDA0ZS1hZmY3LWI5MDc0Zjg2ZDZkMSJ9"
        "400":
          $ref: "#/components/responses/BadRequestError"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /verification-items:
    get:
      tags:
        - Gestion de item Ids
      summary: Obtener todos los items de verificación
      description: |
        Retorna una lista de todos los items de verificación disponibles con paginación basada en tokens.
        La paginación funciona con un tamaño fijo de 10 items por página.
      security:
        - ApiKeyAuth: []
      parameters:
        - name: itemType
          in: query
          required: false
          description: Filtrar por tipo de item (ej. "generic", "csf_mx", etc.)
          schema:
            type: string
        - name: itemStatus
          in: query
          required: false
          description: Filtrar por estado del item (ej. "pending", "complete", "error")
          schema:
            type: string
        - name: tag
          in: query
          required: false
          description: Filtrar por etiqueta de verificación
          schema:
            type: string
        - name: next
          in: query
          required: false
          description: Token de paginación para obtener la siguiente página de resultados
          schema:
            type: string
      responses:
        "200":
          description: Lista de items de verificación obtenida exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/PublicVerificationItem"
                    description: Lista de items de verificación (máximo 10 por página)
                  next:
                    type: string
                    description: Token para obtener la siguiente página de resultados (presente solo si hay más páginas)
                    nullable: true
              examples:
                Success:
                  summary: Lista de items de verificación obtenida exitosamente
                  value:
                    data:
                      - id: 26600
                        item_order: 3
                        item_status: "complete"
                        item_type: "ac_mx"
                        item_internal_status: "classification_failed"
                        item_value:
                          value: "itemCustomed"
                        user_event_completed_at: "2025-09-23T03:30:32Z"
                        user_event_name: "add_item"
                        user_event_reason: "item created without a file_url"
                        tag: null
                        item_scope: "advanced"
                        tags:
                          uploaded-from: "webapp-creation-business"
                        original_file_url: "https://files.staging.gotrebol.com/66b4b55e-0e4f-42ec-9727-2bff88965562/26600_original_file.pdf?response-content-type=application%2Fpdf&response-content-disposition=inline&Expires=1758902113&Key-Pair-Id=K2O2X5EIJK95L0&Signature=X0if4WzR23I0s61h~gW2s-92nGNXhQBHZp9bxl42HqMSMO1VYpybLmhtygyJfx5OvZL4NSoYHTYfH7-yZv02lRwtNSI~xYFAVVxPPFROzwblK66LwymsQWAE0xvwtI98eWQKBWop3rgHADqrUGIm1RBa2qm3Ydlj2HVtWmsrVn2OTMtnIuoyI50Z8iYmx6hcPLul6SazK4h18MMRRi5xnsa2shrGs36rLyRFlnDBObRFJBKmkH4Dn27PuCVrXQRHQwRUIyRCQAiLGSuVKDp~iWZqTld6qgDQOkq-0A54dv0r8O6hYZ5fPyX1ufeIJeaKaGKjKC9qAiOWl~wQe6-w9g__"
                    next: "eyJjcmVhdGVkQXQiOiIyMDI1LTA5LTIzVDAzOjMwOjMyWiIsImlkIjoyNjYwMH0="
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /verification-items/{id}:
    put:
      operationId: confirmarCargaDocumento
      tags:
        - Gestion de item Ids
      summary: Confirmar la carga o reemplazar el archivo de un documento
      description: |
        Después de subir el archivo mediante PUT a `item_options.upload_url`, confirma la carga
        con `options.uploaded_file: true`. También puedes enviar `options.file_url` para
        reemplazar el archivo o reintentar su procesamiento desde una URL descargable.
        Aplica a `generic`, `doc_validation`,
        tipos de extracción de documentos y `doc_splitter`, incluidos los tipos
        personalizados habilitados para la cuenta. El procesamiento es asíncrono.
        Ver [Carga directa](/guia-devs/crear-verificaciones/via-api/carga-directa).
      security:
        - ApiKeyAuth: []
      parameters:
        - name: id
          in: path
          required: true
          description: ID del item recibido al crear la verificación o agregar items.
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [options]
              properties:
                options:
                  type: object
                  anyOf:
                    - required: [uploaded_file]
                    - required: [file_url]
                  allOf:
                    - anyOf:
                        - not:
                            required: [file_password]
                        - required: [uploaded_file]
                          properties:
                            uploaded_file:
                              enum: [true]
                        - required: [file_url]
                  properties:
                    uploaded_file:
                      type: boolean
                      description: Si es true, confirma la carga e inicia el procesamiento. Si es false, no confirma la carga; una file_url enviada en la misma solicitud sí puede iniciar el procesamiento.
                      example: true
                    file_url:
                      type: string
                      minLength: 1
                      description: URL descargable del archivo para reemplazarlo o reintentar su procesamiento. Envíala sin uploaded_file o con uploaded_file en false; conserva la URL disponible al menos 5 minutos.
                      example: "https://example.com/documento.pdf"
                    file_password:
                      type: string
                      minLength: 1
                      maxLength: 128
                      writeOnly: true
                      description: |
                        Contraseña del PDF subido, si está protegido. Envíala junto con `uploaded_file: true` (o con `file_url`); sin un archivo en la misma solicitud la API responde `400` con `code: invalid_item_options_file_password`. Trébol procesa la copia sin contraseña y conserva el original cifrado. Almacena la contraseña cifrada en la base de datos y no la devuelve en respuestas ni webhooks. Si es incorrecta, el ítem termina con `item_error: invalid_file_password`. Se ignora para archivos que no son PDF. Aplica por ítem.
                      example: "clave-del-pdf"
            example:
              options:
                uploaded_file: true
      responses:
        "200":
          description: Solicitud procesada. Con uploaded_file en true o una file_url, solicita el procesamiento del archivo. Con uploaded_file en false y sin file_url, no confirma la carga ni solicita el procesamiento.
          content:
            application/json:
              schema:
                type: object
                properties:
                  item:
                    $ref: "#/components/schemas/PublicVerificationItem"
                  triggeredSideEffects:
                    type: boolean
                    description: Indica si la actualización solicitó el procesamiento del item.
                    example: true
        "400":
          $ref: "#/components/responses/BadRequestError"
        "404":
          description: El item no existe o el archivo aún no está en el almacenamiento de carga.
          content:
            application/json:
              example:
                message: S3 object not found
    get:
      tags:
        - Gestion de item Ids
      summary: Obtener un item de verificación por ID
      description: |
        Retorna un item de verificación específico por su ID.

        **Coordenadas de citas:** para items de tipo acta, agrega `?with_citations=true` y la respuesta incluirá `citations.url` con la URL firmada al artifact de coordenadas de ese documento. Ver [Coordenadas de citas](/guia-devs/referencia/coordenadas-citas).
      security:
        - ApiKeyAuth: []
      parameters:
        - name: id
          in: path
          required: true
          description: El ID único del item de verificación
          schema:
            type: string
        - name: with_citations
          in: query
          required: false
          description: |
            Solo aplica a items de tipo acta. Si es `true`, la respuesta incluye `citations.url`: una URL firmada al artifact de coordenadas de ese documento. Ver [Coordenadas de citas](/guia-devs/referencia/coordenadas-citas).
          schema:
            type: boolean
            default: false
      responses:
        "200":
          description: Item de verificación obtenido exitosamente
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PublicVerificationItem"
              examples:
                Success:
                  summary: Item de verificación obtenido exitosamente
                  value:
                    id: 26600
                    item_order: 3
                    item_status: "complete"
                    item_type: "ac_mx"
                    item_internal_status: "classification_failed"
                    item_value:
                      value: "itemCustomed"
                    user_event_completed_at: "2025-09-23T03:30:32Z"
                    user_event_name: "add_item"
                    user_event_reason: "item created without a file_url"
                    tag: null
                    item_scope: "advanced"
                    tags:
                      uploaded-from: "webapp-creation-business"
                    original_file_url: "https://files.staging.gotrebol.com/66b4b55e-0e4f-42ec-9727-2bff88965562/26600_original_file.pdf?response-content-type=application%2Fpdf&response-content-disposition=inline&Expires=1758902113&Key-Pair-Id=K2O2X5EIJK95L0&Signature=X0if4WzR23I0s61h~gW2s-92nGNXhQBHZp9bxl42HqMSMO1VYpybLmhtygyJfx5OvZL4NSoYHTYfH7-yZv02lRwtNSI~xYFAVVxPPFROzwblK66LwymsQWAE0xvwtI98eWQKBWop3rgHADqrUGIm1RBa2qm3Ydlj2HVtWmsrVn2OTMtnIuoyI50Z8iYmx6hcPLul6SazK4h18MMRRi5xnsa2shrGs36rLyRFlnDBObRFJBKmkH4Dn27PuCVrXQRHQwRUIyRCQAiLGSuVKDp~iWZqTld6qgDQOkq-0A54dv0r8O6hYZ5fPyX1ufeIJeaKaGKjKC9qAiOWl~wQe6-w9g__"
                CustomItemType:
                  summary: Item de un tipo de ítem personalizado (cit_*)
                  value:
                    id: 31544
                    item_order: 1
                    item_status: "complete"
                    item_type: "cit_contrato_arrendamiento"
                    item_internal_status: "extraction_finished"
                    item_error: null
                    item_value:
                      current_stage: "extraction"
                      pipeline:
                        validation:
                          - process_reference: "validar_firmas"
                            executed: true
                            execution_result: true
                            value:
                              identifier: "activeVersionId_87"
                              validation_result: true
                              explanation: "El contrato está firmado por ambas partes."
                        extraction:
                          - process_reference: "extraer_datos_contrato"
                            executed: true
                            execution_result: "success"
                            value:
                              landlord_name: "María López García"
                              tenant_name: "Carlos Ramírez Soto"
                              monthly_rent: 15000
                              start_date: "2026-02-01"
                              contract_duration: "12 meses"
                    original_file_url: "https://files.gotrebol.com/66b4b55e-0e4f-42ec-9727-2bff88965562/31544_original_file.pdf"
                RfcDePruebaSatNoEncontrado:
                  summary: "RFC de prueba B: SAT no encuentra el RFC"
                  description: |
                    Escenario B (`TRB010101NF1`). La consulta corrió bien y el SAT no tiene el RFC: es un resultado definitivo. Ver [RFC de prueba](/guia-devs/pruebas/rfc-de-prueba).
                  value:
                    id: 34173
                    item_order: 15
                    item_status: "complete"
                    item_type: "public_sat_signatures"
                    item_internal_status: "screenshot_taken"
                    item_value:
                      tax_ids: ["TRB010101NF1"]
                      data:
                        TRB010101NF1:
                          status: "fail"
                          tax_id_number: "TRB010101NF1"
                          legal_name: ""
                          business_type: ""
                          certificates: []
                          validation_result:
                            success: false
                            reason: "rfc_not_found"
                          validated_at: "2026-09-10T12:00:30.000Z"
                          scraped_at: "2026-09-10T12:00:30.000Z"
                          screenshot_at: "2026-09-10 12:00:31"
                          screenshot_url: "https://files.gotrebol.com/mx/sat/screenshots/900016/TRB010101NF1/demo.jpg"
                    tag: null
                    item_scope: "advanced"
                    tags: {}
                RfcDePruebaSatFallaTecnica:
                  summary: "RFC de prueba C: falla técnica del SAT"
                  description: |
                    Escenario C (`TRB010101ER1`). La consulta al SAT falló por un problema técnico: vale la pena crear el ítem de nuevo. Ver [RFC de prueba](/guia-devs/pruebas/rfc-de-prueba).
                  value:
                    id: 34188
                    item_order: 15
                    item_status: "complete"
                    item_type: "public_sat_signatures"
                    item_internal_status: "sat_scrap_failed"
                    item_value:
                      tax_ids: ["TRB010101ER1"]
                      data:
                        TRB010101ER1:
                          status: "fail"
                          tax_id_number: "TRB010101ER1"
                          legal_name: ""
                          business_type: ""
                          certificates: []
                          validation_result:
                            success: false
                            reason: "scraper_error"
                          validated_at: "2026-09-10T12:00:30.000Z"
                          scraped_at: "2026-09-10T12:00:30.000Z"
                          screenshot_at: "2026-09-10 12:00:31"
                          screenshot_url: "https://files.gotrebol.com/mx/sat/screenshots/900016/TRB010101ER1/demo.jpg"
                    tag: null
                    item_scope: "advanced"
                    tags: {}
                RfcDePruebaSigerNoEncontrado:
                  summary: "RFC de prueba B: SIGER no encuentra la empresa"
                  description: |
                    Escenario B (`TRB010101NF1`). Resultado definitivo. Ver [RFC de prueba](/guia-devs/pruebas/rfc-de-prueba).
                  value:
                    id: 34172
                    item_order: 14
                    item_status: "complete"
                    item_type: "siger"
                    item_internal_status: "siger_not_found"
                    item_value: {}
                    tag: null
                    item_scope: "advanced"
                    tags: {}
                RfcDePruebaSigerFalla:
                  summary: "RFC de prueba C: falla de SIGER"
                  description: |
                    Escenario C (`TRB010101ER1`). La consulta a SIGER no pudo completarse. Ver [RFC de prueba](/guia-devs/pruebas/rfc-de-prueba).
                  value:
                    id: 34187
                    item_order: 14
                    item_status: "complete"
                    item_type: "siger"
                    item_internal_status: "siger_not_found_ops_forced"
                    item_value: {}
                    tag: null
                    item_scope: "advanced"
                    tags: {}
                RfcDePruebaDocumentoIlegible:
                  summary: "RFC de prueba C: documento que no se pudo leer"
                  description: |
                    Escenario C (`TRB010101ER1`). `item_status` sigue en `complete`: el fallo se lee en `item_error`. Ver [RFC de prueba](/guia-devs/pruebas/rfc-de-prueba).
                  value:
                    id: 34170
                    item_order: 0
                    item_status: "complete"
                    item_type: "ac_mx"
                    item_internal_status: null
                    item_error: "get_input_file_info_failed"
                    item_value: {}
                    tag: null
                    item_scope: "advanced"
                    tags: {}
                RfcDePruebaReglaNoCumplida:
                  summary: "RFC de prueba D: documento que no cumple su regla"
                  description: |
                    Escenario D (`TRB010101DV1`). El tipo es correcto pero la regla no se cumple. No hay `item_error`: el motivo se lee en `rules_validation_result`. Ver [RFC de prueba](/guia-devs/pruebas/rfc-de-prueba).
                  value:
                    id: 34201
                    item_order: 0
                    item_status: "complete"
                    item_type: "doc_validation"
                    item_internal_status: "validation_failed"
                    item_value:
                      rules_validation_result:
                        - id: "vr_trebol_antiguedad"
                          variable_value: "2026-01-10"
                          validation_result: false
                      item_type_validation_result:
                        - validation_result: true
                          reason: "The document is a \"Constancia de Situación Fiscal\" issued by the \"SERVICIO DE ADMINISTRACIÓN TRIBUTARIA\" for a persona moral, with the RFC, \"idCIF\", tax regime, fiscal address and a QR code, which are all strong indicators of a CSF."
                    tag: null
                    item_scope: "advanced"
                    tags: {}
                RfcDePruebaTipoIncorrecto:
                  summary: "RFC de prueba D: documento de otro tipo"
                  description: |
                    Escenario D (`TRB010101DV1`). Se esperaba un estado de cuenta y llegó un recibo de CFE: falla la validación del tipo aunque la regla se cumpla. Ver [RFC de prueba](/guia-devs/pruebas/rfc-de-prueba).
                  value:
                    id: 34204
                    item_order: 3
                    item_status: "complete"
                    item_type: "doc_validation"
                    item_internal_status: "validation_failed"
                    item_value:
                      rules_validation_result:
                        - id: "vr_trebol_antiguedad"
                          variable_value: "2026-08-05"
                          validation_result: true
                      item_type_validation_result:
                        - validation_result: false
                          reason: "The document is a CFE electricity bill (\"Comisión Federal de Electricidad\") for \"COMERCIALIZADORA TRÉBOL DEMO, S.A. DE C.V.\", with the service number, billing period, consumption history and amount due. It is a proof of address, not a bank statement: it has no bank name, CLABE, account number or transaction detail."
                    tag: null
                    item_scope: "advanced"
                    tags: {}
                RfcDePruebaSatRepresentante:
                  summary: "RFC de prueba E: SAT del representante legal"
                  description: |
                    Escenario E (`TRB010101RF1`). El item `representatives` consulta el RFC que nombran los certificados de la empresa en `legalRepresentativeRFC`, no el de la empresa. Ver [RFC de prueba](/guia-devs/pruebas/rfc-de-prueba).
                  value:
                    id: 34211
                    item_order: 1
                    item_status: "complete"
                    item_type: "public_sat_signatures"
                    item_internal_status: "screenshot_taken"
                    item_value:
                      tax_ids: ["RUTD800515AB2"]
                      data:
                        RUTD800515AB2:
                          status: "success"
                          tax_id_number: "RUTD800515AB2"
                          legal_name: "DIEGO ALBERTO RUIZ TORRES"
                          business_type: ""
                          certificates:
                            - numeroSerie: "00001000000700912351"
                              estado: "Activo"
                              tipo: "FIEL"
                              fechaInicial: "2026-04-06T19:05:09.000Z"
                              fechaFinal: "2030-04-06T19:05:49.000Z"
                              personEmail: "firmante@demo.mx"
                              serieLink: "https://rdc.sat.gob.mx/rccf/000010/000007/00/91/23/00001000000700912351.cer"
                            - numeroSerie: "00001000000500912352"
                              estado: "Revocado"
                              tipo: "FIEL"
                              fechaInicial: "2022-05-04T16:52:10.000Z"
                              fechaFinal: "2026-04-06T19:05:09.000Z"
                              serieLink: "https://rdc.sat.gob.mx/rccf/000010/000005/00/91/23/00001000000500912352.cer"
                          validated_at: "2026-09-28T16:35:18.497Z"
                          scraped_at: "2026-09-28T16:35:18.497Z"
                          screenshot_at: "2026-09-28 16:35:27"
                          screenshot_url: "https://files.gotrebol.com/mx/sat/screenshots/900202/RUTD800515AB2/demo.jpg"
                    tag: null
                    item_scope: "advanced"
                    tags: {}
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "404":
          $ref: "#/components/responses/NotFoundError"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /verification-items/{itemId}/invalidate:
    post:
      tags:
        - Invalidar un documento
      summary: Invalidar un documento de una verificacion
      description: Invalida el documento de la verificación especificado.
      parameters:
        - name: itemId
          in: path
          required: true
          description: El ID del documento de verificación que se desea invalidar.
          schema:
            type: string
      requestBody:
        description: No se requiere un cuerpo en la solicitud.
        required: false
        content:
          application/json:
            schema:
              type: object
      responses:
        "200":
          description: sucessful
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "400":
          $ref: "#/components/responses/BadRequestError"
        "500":
          $ref: "#/components/responses/InternalServerError"
      security:
        - ApiKeyAuth: []
  /verifications/{verification-id}:
    get:
      tags:
        - Leer información de la empresa
      summary: Obtener una verificación por su ID
      description: |
        Retorna una verificación pública con sus items serializados.
        Consulta la guía de estructuras de `item_value` por tipo en [Respuestas por tipo de ítem](/docs/guia-devs/respuestas-por-tipo-de-item).

        **Coordenadas de citas:** agrega `?with_citations=true` y los items de tipo acta incluirán un campo `citations.url` con la URL firmada al artifact de coordenadas de ese documento. Ver [Coordenadas de citas](/guia-devs/referencia/coordenadas-citas).

        **Reporte de consultas públicas externas:** cuando la verificación incluye consultas a fuentes externas (SAT, RENAPO, INE, SIGER), la respuesta agrega `lookups_report` con una URL firmada para descargar el reporte PDF de auditoría. El campo se omite si no hay reporte (verificaciones sin consultas externas, antiguas o de países aún no soportados). Ver [Consultas públicas externas](/guia-devs/monitorear/consultas-publicas-externas).

        **Síntesis de Dictamen (`findings`):** la respuesta de este endpoint siempre incluye el campo `findings` con los hallazgos de la Síntesis de Dictamen. El listado `GET /verifications` no lo incluye.

        El bloque completo es `null` mientras la revisión no se haya ejecutado para la verificación. Cuando existe, trae tres campos:

        - `items`: lista de hallazgos, cada uno con `severity` (`high`, `medium` o `low`), `message` y, cuando aplica, `missing_field`. Una lista vacía significa que la revisión corrió y no encontró nada — distinto de `findings: null`.
        - `computed_at`: fecha y hora ISO 8601 de la corrida que produjo los hallazgos. Es `null` en verificaciones antiguas, anteriores a que se registrara este dato.
        - `source`: `provisional` o `final`.

        `source` indica en qué momento Trébol calcula la revisión. `provisional`: la calcula antes de completarse la verificación, con un modelo más rápido, y una corrida final puede reemplazarla — sus hallazgos pueden cambiar de severidad o desaparecer. `final`: la calcula al completarse la verificación.
      operationId: getVerificationById
      parameters:
        - $ref: "#/components/parameters/verificationIdParam"
        - name: with_citations
          in: query
          required: false
          description: |
            Si es `true`, cada item de tipo acta en `items[]` incluye `citations.url`: una URL firmada al artifact de coordenadas de ese documento. Ver [Coordenadas de citas](/guia-devs/referencia/coordenadas-citas).
          schema:
            type: boolean
            default: false
      responses:
        "200":
          description: Verificación recuperada exitosamente.
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/PublicVerification"
                  - type: object
                    required: [findings]
                    properties:
                      findings:
                        $ref: "#/components/schemas/VerificationFindings"
              examples:
                Success:
                  summary: Respuesta exitosa
                  value:
                    id: "c8dc41fc-c477-404e-aff7-b9074f86d6d1"
                    account_id: "99999999-9999-9999-9999-999999999999"
                    status: "pending"
                    created_at: "2025-04-28T20:10:06.840Z"
                    updated_at: "2025-04-28T20:10:06.840Z"
                    tag: "etiqueta"
                    tax_id: "SAG160927GIA"
                    business_name: "Trebol OPCO"
                    friendly_name: "Empresa ACME S.A. de C.V."
                    flow_id: "documents-v2"
                    details_url: "https://app.gotrebol.com/verifications/c8dc41fc-c477-404e-aff7-b9074f86d6d1"
                    onboarding_url: "https://onboarding.gotrebol.com/verification/c8dc41fc..."
                    items:
                      - id: 25440
                        item_status: "pending"
                        item_type: "csf_mx"
                        item_value: {}
                    findings: null
                ConReporteDeConsultas:
                  summary: Respuesta con reporte de consultas públicas externas
                  value:
                    id: "c8dc41fc-c477-404e-aff7-b9074f86d6d1"
                    account_id: "99999999-9999-9999-9999-999999999999"
                    status: "finished"
                    created_at: "2026-06-16T18:00:00.000Z"
                    updated_at: "2026-06-16T18:30:00.000Z"
                    tag: "etiqueta"
                    tax_id: "SAG160927GIA"
                    business_name: "Trebol OPCO"
                    friendly_name: "Empresa ACME S.A. de C.V."
                    flow_id: "documents-v2"
                    items:
                      - id: 25440
                        item_status: "complete"
                        item_type: "public_sat_signatures"
                        item_value: {}
                    lookups_report:
                      url: "https://files.gotrebol.com/.../lookups-report.pdf?...firma..."
                      generated_at: "2026-06-16T18:30:00.000Z"
                    findings:
                      items:
                        - severity: "medium"
                          message: "La estructura accionaria proviene únicamente de SIGER; no fue posible confirmarla con el acta constitutiva proporcionada."
                      computed_at: "2026-06-16T18:30:00.000Z"
                      source: "final"
                ConHallazgosProvisionales:
                  summary: Respuesta con hallazgos provisionales (revisión aún no final)
                  value:
                    id: "c8dc41fc-c477-404e-aff7-b9074f86d6d1"
                    account_id: "99999999-9999-9999-9999-999999999999"
                    status: "pending"
                    created_at: "2026-06-16T18:00:00.000Z"
                    updated_at: "2026-06-16T18:12:00.000Z"
                    tag: "etiqueta"
                    tax_id: "SAG160927GIA"
                    business_name: "Trebol OPCO"
                    friendly_name: "Empresa ACME S.A. de C.V."
                    flow_id: "documents-v2"
                    items:
                      - id: 25441
                        item_status: "complete"
                        item_type: "acta_constitutiva"
                        item_value: {}
                    findings:
                      items:
                        - severity: "high"
                          message: "No se encontró el acta constitutiva; sin ella no es posible confirmar la razón social ni la fecha de constitución."
                          missing_field: "razon_social"
                        - severity: "low"
                          message: "El domicilio fiscal declarado no coincide con el del comprobante de domicilio."
                      computed_at: "2026-06-16T18:12:00.000Z"
                      source: "provisional"
                SinHallazgos:
                  summary: Respuesta con la revisión ejecutada y sin hallazgos
                  value:
                    id: "c8dc41fc-c477-404e-aff7-b9074f86d6d1"
                    account_id: "99999999-9999-9999-9999-999999999999"
                    status: "finished"
                    created_at: "2026-06-16T18:00:00.000Z"
                    updated_at: "2026-06-16T18:30:00.000Z"
                    tax_id: "SAG160927GIA"
                    business_name: "Trebol OPCO"
                    flow_id: "documents-v2"
                    items: []
                    findings:
                      items: []
                      computed_at: "2026-06-16T18:30:00.000Z"
                      source: "final"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "404":
          $ref: "#/components/responses/NotFoundError"
        "500":
          $ref: "#/components/responses/InternalServerError"
      security:
        - ApiKeyAuth: []

  /v2/verifications/{verification-id}/corporate-history:
    get:
      operationId: obtenerHistorialCorporativo
      tags:
        - Leer información de la empresa
      summary: Obtener historial corporativo conciliado
      description: |
        Retorna el historial de actas de una empresa, conciliado entre las tres fuentes que lo conocen, con una fila por acta y la trazabilidad de qué fuente aportó cada dato.

        Ninguna fuente ve la empresa completa, y por eso el historial es el cruce:

        - **`siger`** — el folio mercantil. Es el registro de lo que se inscribió: fechas de inscripción, formas precodificadas y el acto tal como quedó asentado. No ve las actas que nunca se inscribieron, y empieza cuando la empresa se digitalizó.
        - **`client_file`** — los documentos que el cliente subió. Prueba que el acta existe y que la tienen, nunca lo que se acordó en ella.
        - **`background`** — los antecedentes que el fedatario narra al inicio de cada acta. Es la única fuente que ve actas que nadie subió y que el registro nunca inscribió, que suelen ser la mayoría de la historia de una empresa.

        Cada acta declara en `sources` qué fuentes la conocen. Un acta que solo trae `["background"]` existe porque otra acta la cita: llega con `cited_by` y con `evidence`, la cita textual que lo sostiene, y nunca se presenta como un hecho sin respaldo.

        **Se calcula al momento de la consulta**, de forma determinística sobre los datos que ya están en la verificación. No hay copia almacenada, así que la respuesta nunca queda obsoleta — y si los datos son parciales, `coverage` lo dice en vez de que el resultado parezca completo.

        **Las tres fechas de un acta** se distinguen porque se confunden con facilidad: `assembly_date` es cuándo se reunió la asamblea, `instrument_date` cuándo un fedatario la protocolizó y `registration_date` cuándo se inscribió el acta en el Registro público de comercio. `timeline_date` es la llave de orden, con precedencia declarada: instrumento, luego inscripción, luego asamblea. Cuando dos fuentes dan valores distintos para la misma fecha gana el expediente, luego el folio y al final los antecedentes: el expediente tiene el documento en mano, mientras que el folio y los antecedentes solo reportan una lectura de él. Si una misma fuente reporta el acta dos veces —un instrumento inscrito en dos folios— se toma la más antigua, solo para ordenarla.

        **Esta versión no reporta discrepancias entre fuentes.** El valor elegido se entrega sin decir que otra fuente decía algo distinto. Cuando dos antecedentes fechan la misma acta de forma diferente, las dos citas quedan visibles en `evidence`, que es donde la diferencia se puede leer directamente.

        **`coverage` declara hasta dónde vemos**, nunca que el historial esté completo. `combined.no_acta_after` es la fecha del acta más reciente del expediente: un cambio posterior a esa fecha no sería visible ni aunque hubiera ocurrido.

        **`document_check`** es un conteo objetivo, sin ranking. Qué documento faltante importa es política de cada cliente, no una conclusión nuestra: el acta entrega `sources`, `changes[].event_type` y `proof_document`, y quien la lee aplica su propio criterio. La lista de faltantes se deriva del historial mismo, filtrando las actas cuyo `sources` no incluye `client_file`.
      parameters:
        - name: verification-id
          in: path
          required: true
          description: ID de la verificación
          schema: { type: string }
      responses:
        "200":
          description: Historial recuperado exitosamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/V2PublicResponseCorporateHistory"
              examples:
                corporateHistory:
                  $ref: "#/components/examples/V2CorporateHistoryExample"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "404":
          $ref: "#/components/responses/NotFoundError"
        "500":
          $ref: "#/components/responses/InternalServerError"
      security:
        - ApiKeyAuth: []

  /v2/verifications/{verification-id}/{entity}:
    get:
      operationId: obtenerSeccionPorIdDeVerificacion
      tags:
        - Leer información de la empresa
      summary: Obtener sección por ID de verificación
      description: |

        Retorna datos públicos v2 de una sección específica de una verificación a partir de su id.

        **Secciones disponibles:**
        - `details`: Detalles de la empresa (información legal, fiscal, registro, etc.)
        - `shareholders`: Accionistas y capital social
        - `people`: Personas clave, apoderados y representantes legales
        - `documents`: Documentos asociados a la verificación
        - `sources`: Fuentes de información (items) que alimentan la verificación
        - `external-lookups`: Evidencia de auditoría de las consultas a fuentes públicas (SAT, RENAPO, INE, SIGER). Ver [Consultas públicas externas](/guia-devs/monitorear/consultas-publicas-externas).

        **Fuentes (`sources`) y extracciones personalizadas:** cuando la cuenta tiene una extracción personalizada activa para el tipo de ítem correspondiente, cada elemento en `data.sources` puede incluir una llave `cp_<prompt_id>` por cada extracción con resultado, donde `prompt_id` es el identificador editable de la extracción personalizada y el valor es el JSON extraído según el esquema de la versión en uso. Más detalle en la guía [Extracciones personalizadas](/producto/guias/extracciones-personalizadas). Los ítems de tipos de ítem personalizados (`cit_*`) no exponen aquí sus resultados: se leen desde el ítem, en `item_value.pipeline`. Ver [Tipos de ítem personalizados](/producto/guias/tipos-de-item-personalizados#donde-salen-los-resultados).

        **Coordenadas de citas:** agrega `?with_citations=true` para obtener URLs firmadas al artifact de coordenadas. Según la sección: `people` y `shareholders` añaden `data.citations.url`; `sources` añade `citations.url` en cada item de tipo acta del array `data.sources`. Detalle completo en [Coordenadas de citas](/guia-devs/referencia/coordenadas-citas).

        <Accordion title="Endpoints v1 (Legacy)">
          <Warning>
            Estos endpoints están en modo legacy. Te recomendamos migrar al endpoint v2 que consolida toda esta funcionalidad en un solo endpoint con mejor estructura de datos.
          </Warning>

          Los siguientes endpoints v1 están disponibles para compatibilidad con implementaciones existentes:

          - [Obtener estatutos de las actas por el ID de Verificacion](/docs/api-reference/leer-información-de-la-empresa-v1/obtener-estatutos-de-las-actas-por-el-id-de-verificacion)
          - [Obtener documentos de la empresa por id de verificacion](/docs/api-reference/leer-información-de-la-empresa-v1/obtener-documentos-de-la-empresa-por-id-de-verificacion)
          - [Obtener apoderados y representates legales de la empresa de las actas por el ID de Verificacion](/docs/api-reference/leer-información-de-la-empresa-v1/obtener-apoderados-y-representates-legales-de-la-empresa-de-las-actas-por-el-id-de-verificacion)
          - [Obtener accionistas de la empresa de las actas por el ID de Verificacion](/docs/api-reference/leer-información-de-la-empresa-v1/obtener-accionistas-de-la-empresa-de-las-actas-por-el-id-de-verificacion)
          - [Obtener datos de prevalidacion de documentos](/docs/api-reference/leer-información-de-la-empresa-v1/obtener-datos-de-prevalidacion-de-documentos)
        </Accordion>
      parameters:
        - name: id
          in: path
          required: true
          description: ID de la verificación
          schema: { type: string }
        - name: entity
          in: path
          required: true
          description: Sección solicitada
          schema:
            type: string
            enum:
              [
                details,
                shareholders,
                people,
                documents,
                sources,
                external-lookups,
              ]
        - name: with_citations
          in: query
          required: false
          description: |
            Aplica a `people`, `shareholders` y `sources`. Si es `true`:
            - Para `people` y `shareholders`: añade `data.citations.url`, una URL firmada al artifact de coordenadas de esa sección.
            - Para `sources`: añade `citations.url` en cada item de tipo acta dentro de `data.sources`.
            Ver [Coordenadas de citas](/guia-devs/referencia/coordenadas-citas).
          schema:
            type: boolean
            default: false
      responses:
        "200":
          description: Sección recuperada exitosamente.
          content:
            application/json:
              schema:
                oneOf:
                  - title: "Detalles de la empresa"
                    $ref: "#/components/schemas/V2PublicResponseDetails"
                  - title: "Accionistas"
                    $ref: "#/components/schemas/V2PublicResponseShareholders"
                  - title: "Personas"
                    $ref: "#/components/schemas/V2PublicResponsePeople"
                  - title: "Documentos"
                    $ref: "#/components/schemas/V2PublicResponseDocuments"
                  - title: "Fuentes"
                    $ref: "#/components/schemas/V2PublicResponseSources"
                  - title: "Consultas públicas externas"
                    $ref: "#/components/schemas/V2PublicResponseExternalLookups"
              examples:
                details:
                  $ref: "#/components/examples/V2DetailsExample"
                shareholders:
                  $ref: "#/components/examples/V2ShareholdersExample"
                shareholders-rfc-prueba-en-curso:
                  summary: "shareholders: RFC de prueba recién creado"
                  description: |
                    Cualquiera de los tres [RFC de prueba](/guia-devs/pruebas/rfc-de-prueba) mientras las actas se extraen. Vuelve a consultar: la lista se llena al terminar la extracción.
                  value:
                    success: true
                    data:
                      shareholders: []
                      source: null
                      capital: null
                      shareholders_unavailable_reason: "pending_extraction"
                      business_type: null
                    meta:
                      section: "shareholders"
                      verification:
                        id: "115de6ab-0f99-468b-80a4-72bc1f9aa7c9"
                        tag: "prueba-escenario-a"
                        status: "pending"
                shareholders-rfc-prueba-b:
                  summary: "shareholders: RFC de prueba B (sociedad cooperativa)"
                  description: |
                    Escenario B (`TRB010101NF1`). Una sociedad cooperativa no tiene accionistas: la lista vacía es la respuesta final. Ver [RFC de prueba](/guia-devs/pruebas/rfc-de-prueba).
                  value:
                    success: true
                    data:
                      shareholders: []
                      source: null
                      capital: null
                      shareholders_unavailable_reason: "business_type_without_shareholders"
                      business_type: "SOCIEDAD COOPERATIVA LIMITADA"
                    meta:
                      section: "shareholders"
                      verification:
                        id: "bdb0063e-ba71-4fb3-8cb1-0f5293a10677"
                        tag: "prueba-escenario-b"
                        status: "finished"
                people:
                  $ref: "#/components/examples/V2PeopleExample"
                documents:
                  $ref: "#/components/examples/V2DocumentsExample"
                sources:
                  $ref: "#/components/examples/V2SourcesExample"
                external-lookups:
                  $ref: "#/components/examples/V2ExternalLookupsExample"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "404":
          $ref: "#/components/responses/NotFoundError"
        "500":
          $ref: "#/components/responses/InternalServerError"
      security:
        - ApiKeyAuth: []

  /v2/companies/{etiqueta}/{section}:
    get:
      operationId: obtenerSeccionPorEtiquetaDeEmpresa
      tags:
        - Leer información de la empresa
      summary: Obtener sección por etiqueta de empresa
      description: |
        Retorna datos públicos v2 de una sección específica de una empresa a partir de su etiqueta.

        **Secciones disponibles:**
        - `details`: Detalles de la empresa (información legal, fiscal, registro, etc.)
        - `shareholders`: Accionistas y capital social
        - `people`: Personas clave, apoderados y representantes legales
        - `documents`: Documentos asociados a la verificación
        - `sources`: Fuentes de información (items) que alimentan la verificación
        - `external-lookups`: Evidencia de auditoría de las consultas a fuentes públicas (SAT, RENAPO, INE, SIGER). Ver [Consultas públicas externas](/guia-devs/monitorear/consultas-publicas-externas).

        **Fuentes (`sources`) y extracciones personalizadas:** cuando la cuenta tiene una extracción personalizada activa para el tipo de ítem correspondiente, cada elemento en `data.sources` puede incluir una llave `cp_<prompt_id>` por cada extracción con resultado, donde `prompt_id` es el identificador editable de la extracción personalizada y el valor es el JSON extraído según el esquema de la versión en uso. Más detalle en la guía [Extracciones personalizadas](/producto/guias/extracciones-personalizadas). Los ítems de tipos de ítem personalizados (`cit_*`) no exponen aquí sus resultados: se leen desde el ítem, en `item_value.pipeline`. Ver [Tipos de ítem personalizados](/producto/guias/tipos-de-item-personalizados#donde-salen-los-resultados).

        **Coordenadas de citas:** agrega `?with_citations=true` para obtener URLs firmadas al artifact de coordenadas. Según la sección: `people` y `shareholders` añaden `data.citations.url`; `sources` añade `citations.url` en cada item de tipo acta del array `data.sources`. Detalle completo en [Coordenadas de citas](/guia-devs/referencia/coordenadas-citas).

        <Accordion title="Endpoints v1 (Legacy)">
          <Warning>
            Estos endpoints están en modo legacy. Te recomendamos migrar al endpoint v2 que consolida toda esta funcionalidad en un solo endpoint con mejor estructura de datos.
          </Warning>

          Los siguientes endpoints v1 están disponibles para compatibilidad con implementaciones existentes:

          - [Obtener estatutos de las actas por la Etiqueta](/docs/api-reference/leer-información-de-la-empresa-v1/obtener-estatutos-de-las-actas-por-la-etiqueta)
          - [Obtener documentos de la empresa](/docs/api-reference/leer-información-de-la-empresa-v1/obtener-documentos-de-la-empresa)
          - [Obtener apoderados y representantes legales de la empresa de las actas por la Etiqueta](/docs/api-reference/leer-información-de-la-empresa-v1/obtener-apoderados-y-representantes-legales-de-la-empresa-de-las-actas-por-la-etiqueta)
          - [Obtener accionistas de las actas de la empresa por la Etiqueta](/docs/api-reference/leer-información-de-la-empresa-v1/obtener-accionistas-de-las-actas-de-la-empresa-por-la-etiqueta)
          - [Obtener la informacion de la prevalidacion de documentos asosciados a una empresa](/docs/api-reference/leer-información-de-la-empresa-v1/obtener-la-informacion-de-la-prevalidacion-de-documentos-asosciados-a-una-empresa)
        </Accordion>
      parameters:
        - name: id
          in: path
          required: true
          description: Etiqueta de la empresa (tag)
          schema: { type: string }
        - name: section
          in: path
          required: true
          description: Sección solicitada
          schema:
            type: string
            enum:
              [
                details,
                shareholders,
                people,
                documents,
                sources,
                external-lookups,
              ]
        - name: with_citations
          in: query
          required: false
          description: |
            Aplica a `people`, `shareholders` y `sources`. Si es `true`:
            - Para `people` y `shareholders`: añade `data.citations.url`, una URL firmada al artifact de coordenadas de esa sección.
            - Para `sources`: añade `citations.url` en cada item de tipo acta dentro de `data.sources`.
            Ver [Coordenadas de citas](/guia-devs/referencia/coordenadas-citas).
          schema:
            type: boolean
            default: false
      responses:
        "200":
          description: Sección recuperada exitosamente.
          content:
            application/json:
              schema:
                oneOf:
                  - title: "Detalles de la empresa"
                    $ref: "#/components/schemas/V2PublicResponseDetails"
                  - title: "Accionistas"
                    $ref: "#/components/schemas/V2PublicResponseShareholders"
                  - title: "Personas"
                    $ref: "#/components/schemas/V2PublicResponsePeople"
                  - title: "Documentos"
                    $ref: "#/components/schemas/V2PublicResponseDocuments"
                  - title: "Fuentes"
                    $ref: "#/components/schemas/V2PublicResponseSources"
                  - title: "Consultas públicas externas"
                    $ref: "#/components/schemas/V2PublicResponseExternalLookups"
              examples:
                details:
                  $ref: "#/components/examples/V2DetailsExample"
                shareholders:
                  $ref: "#/components/examples/V2ShareholdersExample"
                people:
                  $ref: "#/components/examples/V2PeopleExample"
                documents:
                  $ref: "#/components/examples/V2DocumentsExample"
                sources:
                  $ref: "#/components/examples/V2SourcesExample"
                external-lookups:
                  $ref: "#/components/examples/V2ExternalLookupsExample"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "404":
          $ref: "#/components/responses/NotFoundError"
        "500":
          $ref: "#/components/responses/InternalServerError"
      security:
        - ApiKeyAuth: []

  /v2/verifications/{verification-id}/export/{doc-template-id}:
    get:
      tags:
        - Exportación de Verificaciones
      summary: Exportar datos de verificación a documento personalizado
      description: |
        Exporta los datos de una verificación a un documento personalizado (PDF o Word) reemplazando los IDs con la información extraída.

        El endpoint recibe un documento que contiene IDs (marcadores de posición) que se encuentran documentados en la [sección de plantillas](/docs/plantillas/intro).
        Estos IDs serán reemplazados automáticamente con la información extraída de cada item de la verificación.

        **Funcionalidad:**
        - Genera un diccionario de variables únicas a partir de la información extraída
        - Reemplaza los IDs en el documento con la información correspondiente
        - Retorna el documento procesado con los datos actualizados

        **Tipos de documentos soportados:** PDF, Word (.docx)

      parameters:
        - $ref: "#/components/parameters/verificationIdParam"
        - in: path
          name: doc-template-id
          required: true
          description: El ID de la plantilla de documento. Ver [plantillas de documentos](/plantillas/gestion).
          schema:
            type: string
      responses:
        "200":
          description: JSON con la url de descarga del archivo y otros datos adicionales.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    description: Booleano que indica si la exportación fue exitosa.
                    example: true
                  message:
                    type: string
                    description: Mensaje de éxito.
                    example: "File generated successfully. Download URL provided."
                  download_url:
                    type: string
                    description: URL de descarga del archivo. Al acceder a ella se descargará el archivo automáticamente.
                    example: "https://www.gotrebol.com/download/file.pdf"
                  expires_in:
                    type: number
                    description: Tiempo de expiración del enlace en milisegundos(1 hora).
                    example: 3600000
                  size:
                    type: number
                    description: Tamaño del archivo en bytes.
                    example: 1000000
              examples:
                success:
                  summary: Exportación exitosa
                  value:
                    success: true
                    message: "File generated successfully. Download URL provided."
                    download_rl: "https://www.gotrebol.com/download/file.pdf"
                    expiresIn: 3600000
                    size: 1000000
        "400":
          $ref: "#/components/responses/BadRequestError"
        "404":
          $ref: "#/components/responses/NotFoundError"
        "422":
          description: Verificación sin items o datos insuficientes.
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    example: "verification with no items"
        "500":
          $ref: "#/components/responses/InternalServerError"
      security:
        - ApiKeyAuth: []
    post:
      tags:
        - Exportación de Verificaciones
      summary: Exportar datos de verificación a documento personalizado con variables de apoderados
      description: |
        Exporta los datos de una verificación a un documento personalizado (PDF o Word) reemplazando los IDs con la información extraída, incluyendo el mapeo de variables de apoderados.

        Este endpoint permite especificar qué personas y roles se deben usar para llenar las variables de apoderados en la plantilla. Las variables en la plantilla deben usar la nomenclatura `{key_person_#}` donde `#` es un número (ej: `{key_person_1}`, `{key_person_2}`).

        **Funcionalidad:**
        - Genera un diccionario de variables únicas a partir de la información extraída
        - Reemplaza los IDs en el documento con la información correspondiente
        - Mapea las variables de apoderados (`{key_person_#}`) con las personas y roles especificados en el body
        - Retorna el documento procesado con los datos actualizados

        **Obtener IDs de personas y roles:**
        Los valores de `person_id` y `role_id` se pueden obtener del endpoint [Obtener sección por ID de verificación](https://docs.gotrebol.com/api-reference/leer-información-de-la-empresa/obtener-sección-por-id-de-verificación) bajo la sección `/people`:
        - `person_id`: Se obtiene del campo `people_id` en cada objeto del array `key_people`
        - `role_id`: Se obtiene del campo `id` en cada objeto del array `roles` dentro de cada elemento de `key_people`

        **Tipos de documentos soportados:** PDF, Word (.docx)

      parameters:
        - $ref: "#/components/parameters/verificationIdParam"
        - in: path
          name: doc-template-id
          required: true
          description: El ID de la plantilla de documento. Ver [plantillas de documentos](/plantillas/gestion).
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ExportWithKeyPeopleRequest"
            examples:
              basic:
                summary: Ejemplo básico con dos apoderados
                value:
                  key_people:
                    - key: "key_person_1"
                      person_id: 10
                      role_id: "role_123"
                    - key: "key_person_2"
                      person_id: 15
                      role_id: "role_456"
      responses:
        "200":
          description: JSON con la url de descarga del archivo y otros datos adicionales.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    description: Booleano que indica si la exportación fue exitosa.
                    example: true
                  message:
                    type: string
                    description: Mensaje de éxito.
                    example: "File generated successfully. Download URL provided."
                  download_url:
                    type: string
                    description: URL de descarga del archivo. Al acceder a ella se descargará el archivo automáticamente.
                    example: "https://www.gotrebol.com/download/file.pdf"
                  expires_in:
                    type: number
                    description: Tiempo de expiración del enlace en milisegundos(1 hora).
                    example: 3600000
                  size:
                    type: number
                    description: Tamaño del archivo en bytes.
                    example: 1000000
              examples:
                success:
                  summary: Exportación exitosa
                  value:
                    success: true
                    message: "File generated successfully. Download URL provided."
                    download_url: "https://www.gotrebol.com/download/file.pdf"
                    expiresIn: 3600000
                    size: 1000000
        "400":
          $ref: "#/components/responses/BadRequestError"
        "404":
          $ref: "#/components/responses/NotFoundError"
        "422":
          description: Verificación sin items o datos insuficientes.
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    example: "verification with no items"
        "500":
          $ref: "#/components/responses/InternalServerError"
      security:
        - ApiKeyAuth: []

  /verifications/{verification-id}/findings/run:
    post:
      tags:
        - Síntesis de Dictamen
      summary: Ejecutar la Síntesis de Dictamen bajo demanda
      description: |
        Encola una corrida de la Síntesis de Dictamen (`findings`) para la verificación, sin esperar a que un nuevo documento la dispare automáticamente.

        La corrida pasa por el mismo pipeline con deduplicación que usan las corridas automáticas, así que nunca genera corridas duplicadas.

        **La respuesta es asíncrona.** El endpoint responde `202` en cuanto la corrida queda encolada, sin esperar a que termine; la corrida tarda unos segundos y su resultado se lee en el campo `findings` de [Obtener una verificación por su ID](https://docs.gotrebol.com/api-reference/leer-información-de-la-empresa/obtener-una-verificación-por-su-id). Para saber que terminó, guarda el `findings.computed_at` que tenías antes de llamar y consulta la verificación cada 3-5 segundos hasta que ese valor cambie (o hasta que `findings` deje de ser `null`, si nunca había corrido). Un límite de ~2 minutos es holgado; si se agota, vuelve a consultar más tarde en vez de reintentar el `POST`, porque la corrida encolada sigue en curso.

        A diferencia de las corridas automáticas, una corrida pedida por este endpoint **no exige que haya cambiado algún documento**: varios hallazgos dependen de la vigencia de los documentos, así que las conclusiones pueden cambiar con el calendario aunque las entradas sean idénticas. Para acotar el costo hay un periodo mínimo entre corridas manuales (300 segundos por defecto), que se reporta como `recently_run`.

        El `POST` **no lleva body**; la verificación se identifica por la URL.

        Devuelve `409` con un `error_code` cuando la corrida no procede. Qué hacer en cada caso:

        | `error_code` | Qué pasó | Qué hacer |
        | --- | --- | --- |
        | `not_enabled` | La cuenta no tiene habilitada la Síntesis de Dictamen. | No es activable por API: escríbenos para habilitarla. Reintentar no cambia el resultado. |
        | `pending_documents` | Hay documentos requeridos sin subir o aún en procesamiento. | Sube los que falten. Para saber cuándo reintentar, consulta la verificación y espera a que los items que lista `pending_items` tengan `item_status: "complete"`; no reintentes el `POST` a ciegas. |
        | `already_scheduled` | Ya hay una corrida encolada o en ejecución. | **No reintentes el `POST`**: ya vas a recibir el resultado. Pasa directo a sondear `findings.computed_at`, igual que tras un `202`. |
        | `recently_run` | Hubo una corrida hace muy poco y sigue el periodo mínimo entre corridas manuales. | Espera los segundos que indica `retry_after_seconds` y vuelve a pedirla. |

        Un segundo `POST` mientras hay una corrida en vuelo responde `409 already_scheduled`, nunca un `202` que duplique la corrida.

        Para los códigos de error generales de la API (`401`, `404`, `500`), consulta [Errores](https://docs.gotrebol.com/guia-devs/errores).

        ### Ejemplo

        ```bash
        curl -X POST "https://api.gotrebol.com/verifications/{verification-id}/findings/run" \
          -H "x-api-key: TU_API_KEY"
        ```


        Sustituye `{verification-id}` por el id que te devolvió `POST /verifications` y
        `TU_API_KEY` por tu API key. Si la corrida queda encolada, la respuesta es:


        ```json
        { "status": "queued" }
        ```

        Y el ciclo completo, pidiendo la corrida y esperando su resultado:

        ```js
        const verificationId = "c8dc41fc-c477-404e-aff7-b9074f86d6d1"; // el id de tu verificación
        const headers = { "x-api-key": process.env.TREBOL_API_KEY };
        const base = `https://api.gotrebol.com/verifications/${verificationId}`;
        const sleep = (ms) => new Promise((r) => setTimeout(r, ms));

        // fetch no rechaza ante un status de error: hay que revisarlo a mano, o un
        // 401 durante el sondeo se ve igual que "todavía no termina".
        async function getVerification() {
          const res = await fetch(base, { headers });
          if (!res.ok) throw new Error(`Trébol respondió ${res.status}`);
          return res.json();
        }

        // 1. Guarda el computed_at actual: es la referencia para saber si ya corrió.
        const previous = (await getVerification()).findings?.computed_at ?? null;

        // 2. Pide la corrida, reintentando cuando el cooldown lo pide.
        while (true) {
          const run = await fetch(`${base}/findings/run`, { method: "POST", headers });
          if (run.status === 202) break;
          if (run.status !== 409) throw new Error(`Trébol respondió ${run.status}`);

          const { error_code, retry_after_seconds } = await run.json();
          // Ya hay una corrida en vuelo: su resultado es el que esperas igual.
          if (error_code === "already_scheduled") break;
          // Corrió hace poco. Es el caso normal al revalidar por vigencia.
          if (error_code === "recently_run") {
            await sleep((retry_after_seconds ?? 60) * 1000);
            continue;
          }
          // not_enabled y pending_documents no se resuelven reintentando.
          throw new Error(`corrida rechazada: ${error_code}`);
        }

        // 3. Sondea hasta que computed_at cambie (~2 min es holgado).
        const deadline = Date.now() + 120_000;
        while (Date.now() < deadline) {
          await sleep(4000);
          const { findings } = await getVerification();
          if (findings?.computed_at && findings.computed_at !== previous) {
            return findings; // hallazgos frescos
          }
        }
        // Se agotó la espera. La corrida sigue en curso: no es un fallo, así que
        // devuelve los hallazgos que ya tenías y vuelve a consultar más tarde.
        return (await getVerification()).findings;
        ```
      operationId: ejecutarRevisionDeHallazgos
      # Pin the generated page's URL. Mintlify builds it from the tag + summary,
      # which are accented Spanish, so the default route lands on
      # /api-reference/síntesis-de-dictamen/… — a URL that percent-encodes to
      # mojibake the moment anyone copies or pastes it. Display text keeps its
      # accents; only the slug is ASCII.
      x-mint:
        href: "/api-reference/sintesis-de-dictamen/ejecutar-sintesis-de-dictamen-bajo-demanda"
      parameters:
        - $ref: "#/components/parameters/verificationIdParam"
      responses:
        "202":
          description: Corrida de hallazgos encolada.
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    enum: [queued]
                    description: Estado de la solicitud. Siempre `queued` cuando la corrida queda encolada.
              example:
                status: "queued"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "404":
          $ref: "#/components/responses/NotFoundError"
        "409":
          description: La corrida no procede en el estado actual de la verificación. Revisa `error_code` para saber la causa.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/FindingsRunConflict"
              examples:
                NotEnabled:
                  summary: not_enabled
                  value:
                    error_code: "not_enabled"
                    message: "The findings analysis is not enabled for this account."
                PendingDocuments:
                  summary: pending_documents
                  value:
                    error_code: "pending_documents"
                    pending_items: ["Acta constitutiva", "constancia_situacion_fiscal_mx"]
                    message: "Findings cannot run yet: some required documents are still uploading or being processed."
                AlreadyScheduled:
                  summary: already_scheduled
                  value:
                    error_code: "already_scheduled"
                    message: "A findings run is already queued or in progress for this verification."
                RecentlyRun:
                  summary: recently_run
                  value:
                    error_code: "recently_run"
                    retry_after_seconds: 240
                    message: "Findings were recalculated moments ago. Try again in 240 seconds."
        "500":
          $ref: "#/components/responses/InternalServerError"
      security:
        - ApiKeyAuth: []

  /verifications/{verification-id}/labels:
    put:
      tags:
        - Labels de Verificacion
      summary: Actualizar labels de una verificacion
      description: Actualiza los labels de una verificación específica. Estos labels son útiles para identificar y buscar verificaciones.
      parameters:
        - in: path
          name: verification-id
          required: true
          description: El ID de la verificación.
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                label_ids:
                  type: array
                  description: |
                    Una lista de IDs de labels que se asignarán a la verificación.
                    Estos son los ID de los labels globales que se pueden asignar a las verificaciones:
                    - 1: "Verificación rechazada"
                    - 2: "Verificación aprobada"
                    - 3: "Verificación invalidada"
                  items:
                    type: number
                    example: 3
              example: |
                {
                  "label_ids": [3]
                }
      responses:
        "200":
          description: Labels actualizados exitosamente.
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    example: "Labels updated successfully"
        "400":
          $ref: "#/components/responses/BadRequestError"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "404":
          $ref: "#/components/responses/NotFoundError"
        "500":
          $ref: "#/components/responses/InternalServerError"
      security:
        - ApiKeyAuth: []

  /verifications/{verification-id}/key-people:
    put:
      tags:
        - Actualizar personas clave de una verificacion
      summary: Actualizar personas clave de una verificacion
      description: Actualiza las personas clave de una verificación específica.
      parameters:
        - in: path
          name: verification-id
          required: true
          description: El ID de la verificación.
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                key_people:
                  type: array
                  description: |
                    Una lista de personas clave que se asignarán a la verificación.
                    Cada persona clave debe tener un nombre y un alcance.
                  items:
                    type: object
                    properties:
                      names:
                        type: string
                        description: El nombre de la persona clave.
                      scope:
                        type: array
                        description: |
                          El alcance o las responsabilidades de la persona dentro de la empresa.
                        items:
                          type: string
                          example: "powers"
              example:
                {
                  "key_people":
                    [
                      { "names": "John Smith", "scope": ["powers"] },
                      { "names": "Jane Doe", "scope": ["powers"] },
                    ],
                }
      responses:
        "200":
          description: Personas clave actualizadas exitosamente.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  message:
                    type: string
                    example: "added key people successfully"
        "400":
          $ref: "#/components/responses/BadRequestError"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "404":
          $ref: "#/components/responses/NotFoundError"
        "500":
          $ref: "#/components/responses/InternalServerError"
      security:
        - ApiKeyAuth: []

  /verifications/{verification-id}/add-items:
    put:
      tags:
        - Agregar items a una verificacion
      summary: Agregar items a una verificación existente
      description: |
        Agrega nuevos items/documentos a una verificación específica usando el id de la verificación.

        **Flujo de trabajo:**
        - **Paso 2 (Validación)**: Agregar items tipo `doc_validation` para validar documentos
        - **Paso 5 (Extracción)**: Agregar items de extracción real (`ac_mx`, `csf_mx`, etc.) basados en resultados de validación
      parameters:
        - in: path
          name: verification-id
          required: true
          description: El ID de la verificación.
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - items
              properties:
                items:
                  type: array
                  description: |
                    Una lista de ítems o documentos que serán agregados a la verificación, cada item debe tener un tipo y opciones.
                  items:
                    type: object
                    required:
                      - type
                      - options
                    properties:
                      type:
                        type: string
                        description: |
                          El tipo de documento o ítem a procesar. Acepta cualquier tipo soportado por Trébol.
                          - **Clasificación**: `generic` (Trébol detecta el tipo automáticamente).
                          - **Validación**: `doc_validation` (requiere `options.client_item_type`).
                          - **División de PDFs multi-documento**: `doc_splitter` (ver [guía del divisor de documentos](/producto/guias/doc-splitter)).
                          - **Extractores built-in México**: `ac_mx` (acta constitutiva), `aa_mx` (acta de asamblea), `pw_mx` (poder), `fme_mx` (fusión/escisión), `csf_mx` (constancia SAT), `union_documents_extractor`, entre otros.
                          - **Tipos personalizados**: nombres con prefijo `cit_` definidos en [tipos de ítem personalizados](/producto/guias/tipos-de-item-personalizados).

                          La lista completa vive en `SUPPORTED_ITEM_TYPES` del backend y crece con nuevos extractores; para ver la forma de respuesta por cada tipo consulta [respuestas por tipo de item](/guia-devs/referencia/respuestas-por-tipo-de-item).
                        example: "doc_validation"
                      tags:
                        type: object
                        description: Mapa de etiquetas que se asignarán al ítem como pares clave-valor.
                        additionalProperties:
                          type: string
                        example:
                          client_id: "some-client-id"
                      options:
                        type: object
                        description: |
                          Opciones adicionales para el ítem. Para el origen del archivo envía **uno** de:
                          `file_url` (URL descargable) o `file_source: "item"` (para referenciar un corte de un `doc_splitter`).
                          Si omites ambos, Trébol devuelve una `upload_url` presignada (ver [flujo de carga directa](/guia-devs/crear-verificaciones/via-api/carga-directa)). Este flujo también aplica a `doc_splitter`: sube el archivo y confirma con `options.uploaded_file: true`.
                        properties:
                          file_url:
                            type: string
                            description: URL de un archivo presignado que se puede descargar para el ítem a verificar.
                            example: "https://www.googleapis.com/downloadableFile"
                          file_password:
                            type: string
                            minLength: 1
                            maxLength: 128
                            writeOnly: true
                            description: |
                              Contraseña del PDF cuando el archivo está protegido. Trébol abre el documento con ella al recibirlo, procesa la copia sin contraseña y conserva el archivo original cifrado. Trébol almacena la contraseña cifrada en la base de datos y no la devuelve en respuestas ni webhooks. Si la contraseña es incorrecta, el ítem termina con `item_error: invalid_file_password`. Se ignora para archivos que no son PDF. Aplica por ítem.
                            example: "clave-del-pdf"
                          constancia_type:
                            type: string
                            description: Tipo de constancia para items csf_mx (opcional). Especifica si es para empresa o individuo.
                            enum: ["business", "individual"]
                            example: "business"
                          people_scope:
                            type: array
                            description: Especifica el alcance de las personas que deben ser consideradas en la verificación.
                            items:
                              type: string
                              example: "powers"
                          client_item_type:
                            $ref: "#/components/schemas/ClientItemType"
                          allowed_item_types:
                            type: array
                            description: |
                              Solo para `doc_splitter`. Restringe los tipos que el splitter puede identificar. Acepta tipos built-in (por ejemplo `ac_mx`, `aa_mx`) y nombres de tipos de ítem personalizados (`cit_...`). Si se omite o está vacío, se usa el catálogo base completo.
                              **No confundir con** el `allowed_item_types` del `RequirementDefinition` (schema `AllowedItemType`): aquel es un enum cerrado usado en `record_validation_schema` para definir qué tipos satisfacen un requerimiento del expediente.
                            items:
                              type: string
                            example: ["ac_mx", "aa_mx"]
                          file_source:
                            type: string
                            description: |
                              Origen del archivo. Envía `"item"` para referenciar un corte generado por un ítem `doc_splitter` previo; en ese caso, completa `file_source_info` con `item_id` y `support_id`. Detalle en la [guía del divisor de documentos](/producto/guias/doc-splitter).
                            enum: ["item"]
                          file_source_info:
                            type: object
                            description: |
                              Referencia al corte del `doc_splitter`. Requerido cuando `file_source: "item"`. Trébol resuelve el sub-PDF internamente; no envíes `bucket`, `key` ni `support_url`.
                            properties:
                              item_id:
                                type: integer
                                description: "`id` del ítem `doc_splitter` que produjo el corte."
                                example: 30829
                              support_id:
                                type: string
                                description: |
                                  Identificador del sub-recurso dentro del ítem referenciado por `item_id`. Para un `doc_splitter` este valor es el `support_id` del corte que Trébol expone en `item_value.split_documents[].support_id`.
                                example: "ds_9f7d3a1c-1c72-4b0f-b8e2-5c9c8b5d4a11"
                            required:
                              - item_id
                              - support_id
            examples:
              Step2Validation:
                summary: Paso 2 - Validación de documentos
                value:
                  items:
                    - type: "doc_validation"
                      options:
                        file_url: "https://www.googleapis.com/downloadableFile"
                      tags:
                        some: "tag value"
              Step5Extraction:
                summary: Paso 5 - Extracción de información
                value:
                  items:
                    - type: "ac_mx"
                      options:
                        file_url: "https://www.googleapis.com/downloadableFile"
                      tags:
                        some: "tag value"
                    - type: "union_documents_extractor"
                      options:
                        file_url: "https://www.googleapis.com/downloadableFile"
                      tags:
                        some: "tag value"
                    - type: "csf_mx"
                      options:
                        file_url: "https://www.googleapis.com/downloadableFile"
                        constancia_type: "business"
                      tags:
                        some: "tag value"
              DocSplitterCreate:
                summary: Crear un doc_splitter para dividir un PDF con varios documentos
                value:
                  items:
                    - type: "doc_splitter"
                      options:
                        file_url: "https://ejemplo.com/expediente-completo.pdf"
                        allowed_item_types:
                          ["ac_mx", "aa_mx", "pw_mx", "fme_mx"]
              DocSplitterConsume:
                summary: Crear un ítem a partir de un corte de un doc_splitter
                value:
                  items:
                    - type: "ac_mx"
                      options:
                        file_source: "item"
                        file_source_info:
                          item_id: 30829
                          support_id: "ds_9f7d3a1c-1c72-4b0f-b8e2-5c9c8b5d4a11"
      responses:
        "200":
          description: Items agregados exitosamente a la verificación.
          content:
            application/json:
              schema:
                type: array
                description: Lista de items agregados con sus IDs asignados.
                items:
                  type: object
                  properties:
                    id:
                      type: integer
                      description: ID del ítem/documento.
                      example: 25440
                    item_status:
                      type: string
                      description: Estado del ítem/documento.
                      example: "pending"
                      enum: [pending, complete]
                    item_type:
                      type: string
                      description: Tipo de ítem/documento.
                      example: "ubos"
                    item_value:
                      type: object
                      description: Valores especificos del ítem/documento.
                    item_options:
                      type: object
                      description: Opciones adicionales del ítem/documento que afectan al proceso interno del mismo.
                      properties:
                        upload_url:
                          type: string
                          format: uri
                          description: URL firmada temporal para subir el archivo del item mediante PUT antes de confirmar con options.uploaded_file.
                        is_optional:
                          type: boolean
                          description: Indica si el ítem/documento es opcional.
                          example: true
                      nullable: true
        "400":
          $ref: "#/components/responses/BadRequestError"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "404":
          $ref: "#/components/responses/NotFoundError"
        "409":
          description: |
            Conflicto. Causa habitual al referenciar un corte de `doc_splitter` con `file_source: "item"`: `source_item_not_ready` — el ítem fuente aún no está en `complete` sin `item_error`. Ver [Errores HTTP al referenciar un corte](/producto/guias/doc-splitter#errores-http-al-referenciar-un-corte).
        "500":
          $ref: "#/components/responses/InternalServerError"
      security:
        - ApiKeyAuth: []

  /verifications/{verification-id}/record_validation:
    get:
      tags:
        - Estado de validacion de documentos
      summary: Obtener estado de validacion de documentos por el ID de Verificacion
      description: Obtener el estado de validacion de documentos de una verificacion usando el id de la verificación.
      parameters:
        - in: path
          name: verification-id
          required: true
          description: El ID de la verificación.
          schema:
            type: string
      responses:
        "200":
          description: Estado de validacion de documentos recuperado exitosamente.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      version:
                        type: number
                        example: 2
                      requirements:
                        type: object
                  verification:
                    type: object
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "404":
          $ref: "#/components/responses/NotFoundError"
        "500":
          $ref: "#/components/responses/InternalServerError"
      security:
        - ApiKeyAuth: []

  /account-flows:
    get:
      tags: ["Gestión de Flujos de Cuenta"]
      summary: Listar flujos de cuenta
      description: Obtiene una lista de todos los flujos de cuenta
      responses:
        "200":
          description: Lista de flujos recuperada exitosamente
          content:
            application/json:
              schema:
                type: array
                items:
                  allOf:
                    - $ref: "#/components/schemas/AccountFlow"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "404":
          $ref: "#/components/responses/NotFoundError"
        "500":
          $ref: "#/components/responses/InternalServerError"
      security:
        - ApiKeyAuth: []

    post:
      tags: ["Gestión de Flujos de Cuenta"]
      summary: Crear nuevo flujo
      description: |
        Crea un nuevo flujo de cuenta. Visita la [guía de desarrollo](/guia-devs/crear-verificaciones/via-widget/crear-flujo) para más información.

        > **Nota:** El cuerpo de la solicitud está limitado a **200 KB** por nuestro WAF. Si tu configuración (reglas de validación, esquemas de formulario, listas de `flow_items`, etc.) supera este tamaño, la solicitud será rechazada antes de llegar al backend. Revisa las [recomendaciones de la guía](/guia-devs/account-flows) para mantenerte dentro del límite.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              allOf:
                - $ref: "#/components/schemas/AccountFlowCreate"
            examples:
              CreateFlow:
                summary: Crear nuevo flujo de cuenta
                value:
                  friendly_name: "A FLOW name test"
                  id_slug: "id-test-flow"
                  flow_items:
                    id: "enterprise-example-2"
                    items:
                      - type: "rues"
                        options:
                          nit: ""
                      - type: "ubos"
                        options:
                          ubos_data_extraction: true
                      - type: "forms"
                        options:
                          schema_id: "some-test-form-schema"
                          is_optional: true
                    options:
                      creator_email: "jsmith@example.com"
                      next_steps_checkout:
                        - title: "Documentos adicionales"
                          description: "Es posible que se necesiten documentos adicionales para completar tu onboarding. En ese caso nos pondremos en contacto contigo."
                        - title: "Firma del contrato"
                          description: "Cuando se complete toda la información, un representante de ventas se pondrá en contacto contigo para firmar el contrato."
                  record_validation_schema:
                    version: 2
                    requirements:
                      doc_1:
                        ui_options:
                          label: "Poderes del representante legal"
                          description: "Documento que certifica que el representante legal tiene los poderes para representar a la empresa."
                          conditional_render: true
                          conditional_render_label: "¿Los poderes del representante legal figuran en un acta de asamblea o poder notarial?"
                        allowed_item_types:
                          - "pw_mx"
                          - "ac_mx"
                          - "aa_mx"
                    optional_requirements: {}
                  country: "mx"
      responses:
        "201":
          description: Flujo creado exitosamente
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/AccountFlow"
        "400":
          $ref: "#/components/responses/BadRequestError"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "500":
          $ref: "#/components/responses/InternalServerError"
      security:
        - ApiKeyAuth: []

  /account-flows/{id_slug}:
    get:
      tags: ["Gestión de Flujos de Cuenta"]
      summary: Obtener flujo por ID
      description: Recupera un flujo de cuenta específico por su id_slug.
      parameters:
        - name: id_slug
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: Flujo recuperado exitosamente
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/AccountFlow"
                  - type: object
                    properties:
                      country:
                        type: string
                        enum: ["mx", "co"]
                        description: País al que pertenece el flujo
                      id_slug:
                        type: string
                        description: Identificador único del flujo
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "404":
          $ref: "#/components/responses/NotFoundError"
        "500":
          $ref: "#/components/responses/InternalServerError"
      security:
        - ApiKeyAuth: []

    delete:
      operationId: deleteAccountFlow
      tags: ["Gestión de Flujos de Cuenta"]
      summary: Eliminar flujo existente
      description: Elimina un flujo de cuenta existente por su id_slug
      parameters:
        - name: id_slug
          in: path
          required: true
          description: Identificador único del flujo a eliminar
          schema:
            type: string
      responses:
        "200":
          description: Flujo eliminado exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  message:
                    type: string
                    example: "Flujo eliminado correctamente"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "404":
          $ref: "#/components/responses/NotFoundError"
        "500":
          $ref: "#/components/responses/InternalServerError"
      security:
        - ApiKeyAuth: []

    put:
      tags: ["Gestión de Flujos de Cuenta"]
      summary: Actualizar flujo existente
      description: |
        Actualiza un flujo de cuenta existente por su id_slug.

        > **Nota:** El cuerpo de la solicitud está limitado a **200 KB** por nuestro WAF. Si tu configuración (reglas de validación, esquemas de formulario, listas de `flow_items`, etc.) supera este tamaño, la solicitud será rechazada antes de llegar al backend. Revisa las [recomendaciones de la guía](/guia-devs/account-flows) para mantenerte dentro del límite.
      parameters:
        - name: id_slug
          in: path
          required: true
          description: Identificador único del flujo a actualizar
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              allOf:
                - $ref: "#/components/schemas/AccountFlowUpdate"
                - type: object
                  properties:
                    country:
                      type: string
                      enum: ["mx", "co"]
                      description: País al que pertenece el flujo
      responses:
        "200":
          description: Flujo actualizado exitosamente
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/AccountFlow"
                  - type: object
                    properties:
                      country:
                        type: string
                        enum: ["mx", "co"]
                        description: País al que pertenece el flujo
                      id_slug:
                        type: string
                        description: Identificador único del flujo
        "400":
          $ref: "#/components/responses/BadRequestError"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "404":
          $ref: "#/components/responses/NotFoundError"
        "500":
          $ref: "#/components/responses/InternalServerError"
      security:
        - ApiKeyAuth: []

  /v2/form-schemas:
    get:
      tags: ["Gestión de Esquemas de Formularios"]
      summary: Listar esquemas de formularios
      description: Obtiene una lista de todos los esquemas de formularios de la cuenta
      responses:
        "200":
          description: Lista de esquemas recuperada exitosamente
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/PublicFormSchema"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "404":
          $ref: "#/components/responses/NotFoundError"
        "500":
          $ref: "#/components/responses/InternalServerError"
      security:
        - ApiKeyAuth: []

    post:
      tags: ["Gestión de Esquemas de Formularios"]
      summary: Crear nuevo esquema de formulario
      description: |
        Crea un nuevo esquema de formulario para la cuenta.

        > **Nota:** El cuerpo de la solicitud está limitado a **200 KB** por nuestro WAF. Si tu esquema (campos, `ui_label`, `description`, validaciones, etc.) supera este tamaño, la solicitud será rechazada antes de llegar al backend. Considera dividir formularios muy grandes en varios esquemas más pequeños.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: ["name", "id_schema", "ui_schema_definition"]
              properties:
                name:
                  type: string
                  description: Nombre del esquema de formulario
                  example: "Formulario de Onboarding"
                id_schema:
                  type: string
                  description: Identificador único del esquema
                  example: "onboarding-form"
                ui_schema_definition:
                  $ref: "#/components/schemas/UISchemaField"
      responses:
        "200":
          description: Esquema creado exitosamente
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PublicFormSchema"
        "400":
          $ref: "#/components/responses/BadRequestError"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "500":
          $ref: "#/components/responses/InternalServerError"
      security:
        - ApiKeyAuth: []

  /v2/form-schemas/{id_schema}:
    get:
      tags: ["Gestión de Esquemas de Formularios"]
      summary: Obtener esquema por ID
      description: Recupera un esquema de formulario específico por su id_schema
      parameters:
        - name: id_schema
          in: path
          required: true
          schema:
            type: string
            description: Identificador único del esquema
      responses:
        "200":
          description: Esquema recuperado exitosamente
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PublicFormSchema"
        "400":
          $ref: "#/components/responses/BadRequestError"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "500":
          $ref: "#/components/responses/InternalServerError"
      security:
        - ApiKeyAuth: []

    put:
      tags: ["Gestión de Esquemas de Formularios"]
      summary: Actualizar esquema existente
      description: |
        Actualiza un esquema de formulario existente por su id_schema.

        > **Nota:** El cuerpo de la solicitud está limitado a **200 KB** por nuestro WAF. Si tu esquema (campos, `ui_label`, `description`, validaciones, etc.) supera este tamaño, la solicitud será rechazada antes de llegar al backend. Considera dividir formularios muy grandes en varios esquemas más pequeños.
      parameters:
        - name: id_schema
          in: path
          required: true
          schema:
            type: string
            description: Identificador único del esquema
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  description: Nombre del esquema de formulario
                ui_schema_definition:
                  $ref: "#/components/schemas/UISchemaField"
      responses:
        "200":
          description: Esquema actualizado exitosamente
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PublicFormSchema"
        "400":
          $ref: "#/components/responses/BadRequestError"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "404":
          $ref: "#/components/responses/NotFoundError"
        "500":
          $ref: "#/components/responses/InternalServerError"
      security:
        - ApiKeyAuth: []

    delete:
      tags: ["Gestión de Esquemas de Formularios"]
      summary: Eliminar esquema existente
      description: Elimina un esquema de formulario existente por su id_schema
      parameters:
        - name: id_schema
          in: path
          required: true
          schema:
            type: string
            description: Identificador único del esquema
      responses:
        "200":
          description: Esquema eliminado exitosamente
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    example: "Form schema deleted successfully"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "404":
          $ref: "#/components/responses/NotFoundError"
        "500":
          $ref: "#/components/responses/InternalServerError"
      security:
        - ApiKeyAuth: []

  /whitelist-ips:
    get:
      tags:
        - Gestión de IPs Permitidas
      summary: Obtener lista de IPs permitidas para hacer llamadas a la API
      description: |
        Obtiene la lista de IPs permitidas para la cuenta del cliente. Si no hay IPs configuradas, 
        no se realiza validación de origen de las llamadas a la API. Si hay al menos una IP configurada, 
        todas las llamadas a la API deben provenir de estas IPs.
      responses:
        "200":
          description: Lista de IPs permitidas recuperada exitosamente.
          content:
            application/json:
              schema:
                type: object
                properties:
                  ips:
                    type: array
                    description: Lista de direcciones IP permitidas (IPv4 e IPv6).
                    items:
                      type: string
                      pattern: '^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$|^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$|^(?:[0-9a-fA-F]{1,4}:){1,7}:$|^(?:[0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}$|^(?:[0-9a-fA-F]{1,4}:){1,5}(?::[0-9a-fA-F]{1,4}){1,2}$|^(?:[0-9a-fA-F]{1,4}:){1,4}(?::[0-9a-fA-F]{1,4}){1,3}$|^(?:[0-9a-fA-F]{1,4}:){1,3}(?::[0-9a-fA-F]{1,4}){1,4}$|^(?:[0-9a-fA-F]{1,4}:){1,2}(?::[0-9a-fA-F]{1,4}){1,5}$|^[0-9a-fA-F]{1,4}:(?:(?::[0-9a-fA-F]{1,4}){1,6})$|^:(?:(?::[0-9a-fA-F]{1,4}){1,7}|:)$'
                    example: ["192.168.1.1", "10.0.0.0/24", "2001:db8::1"]
                  count:
                    type: integer
                    description: Número total de IPs permitidas.
                    example: 3
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "404":
          $ref: "#/components/responses/NotFoundError"
        "500":
          $ref: "#/components/responses/InternalServerError"
      security:
        - ApiKeyAuth: []

    post:
      tags:
        - Gestión de IPs Permitidas
      summary: Agregar IPs a la lista de permitidas para hacer llamadas a la API
      description: |
        Agrega una o más direcciones IP a la lista de IPs permitidas. Si es la primera IP que se agrega, 
        automáticamente se activa la validación de origen para todas las llamadas a la API.
        Máximo 100 IPs permitidas por cuenta.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - ips
              properties:
                ips:
                  type: array
                  description: Lista de direcciones IP a agregar (IPv4 e IPv6).
                  minItems: 1
                  maxItems: 100
                  items:
                    type: string
                    pattern: '^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$|^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$|^(?:[0-9a-fA-F]{1,4}:){1,7}:$|^(?:[0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}$|^(?:[0-9a-fA-F]{1,4}:){1,5}(?::[0-9a-fA-F]{1,4}){1,2}$|^(?:[0-9a-fA-F]{1,4}:){1,4}(?::[0-9a-fA-F]{1,4}){1,3}$|^(?:[0-9a-fA-F]{1,4}:){1,3}(?::[0-9a-fA-F]{1,4}){1,4}$|^(?:[0-9a-fA-F]{1,4}:){1,2}(?::[0-9a-fA-F]{1,4}){1,5}$|^[0-9a-fA-F]{1,4}:(?:(?::[0-9a-fA-F]{1,4}){1,6})$|^:(?:(?::[0-9a-fA-F]{1,4}){1,7}|:)$'
            examples:
              SingleIP:
                summary: Agregar una sola IP
                value:
                  ips: ["192.168.1.1"]
              MultipleIPs:
                summary: Agregar múltiples IPs
                value:
                  ips: ["192.168.1.1", "10.0.0.0/24", "2001:db8::1"]
      responses:
        "200":
          description: IPs added successfully.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  message:
                    type: string
                    example: "IPs added successfully"
                  added_ips:
                    type: array
                    description: Lista de IPs que fueron agregadas.
                    items:
                      type: string
                    example: ["192.168.1.1", "10.0.0.0/24"]
                  total_ips:
                    type: integer
                    description: Número total de IPs permitidas después de la operación.
                    example: 5
        "400":
          $ref: "#/components/responses/BadRequestError"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "413":
          description: Maximum number of IPs (100) would be exceeded
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              examples:
                IpsLimitExceeded:
                  summary: Límite de IPs excedido
                  value:
                    success: false
                    message: "Maximum number of IPs (100) would be exceeded"
                    current_count: 100
                    max_allowed: 100
                    request_count: 101
        "500":
          $ref: "#/components/responses/InternalServerError"
      security:
        - ApiKeyAuth: []

    delete:
      tags:
        - Gestión de IPs Permitidas
      summary: Eliminar todas las IPs permitidas
      description: |
        Elimina todas las IPs de la lista de permitidas. Después de esta operación, 
        no se realizará validación de origen para las llamadas a la API.
      responses:
        "200":
          description: All IPs have been deleted
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  message:
                    type: string
                    example: "All IPs have been deleted"
                  deleted_count:
                    type: integer
                    description: Número de IPs que fueron eliminadas.
                    example: 5
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "500":
          $ref: "#/components/responses/InternalServerError"
      security:
        - ApiKeyAuth: []

  /whitelist-ips/{ip}:
    delete:
      tags:
        - Gestión de IPs Permitidas
      summary: Eliminar IP específica de la lista de permitidas
      description: |
        Elimina una dirección IP específica de la lista de IPs permitidas. 
        Si se elimina la última IP, se desactiva la validación de origen.
      parameters:
        - name: ip
          in: path
          required: true
          description: |
            Dirección IP a eliminar (IPv4 o IPv6).
            Para eliminar una IP con formato CIDR, es necesario codificar el `/` como `%2F`. Por ejemplo, para eliminar la IP `10.0.0.0/24`, la URL deberia ser `/whitelist-ips/10.0.0.0%2F24`.
          schema:
            type: string
            pattern: '^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$|^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$|^(?:[0-9a-fA-F]{1,4}:){1,7}:$|^(?:[0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}$|^(?:[0-9a-fA-F]{1,4}:){1,5}(?::[0-9a-fA-F]{1,4}){1,2}$|^(?:[0-9a-fA-F]{1,4}:){1,4}(?::[0-9a-fA-F]{1,4}){1,3}$|^(?:[0-9a-fA-F]{1,4}:){1,3}(?::[0-9a-fA-F]{1,4}){1,4}$|^(?:[0-9a-fA-F]{1,4}:){1,2}(?::[0-9a-fA-F]{1,4}){1,5}$|^[0-9a-fA-F]{1,4}:(?:(?::[0-9a-fA-F]{1,4}){1,6})$|^:(?:(?::[0-9a-fA-F]{1,4}){1,7}|:)$'
            example: "192.168.1.1"
      responses:
        "200":
          description: IP eliminada exitosamente.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  message:
                    type: string
                    example: "IP eliminada exitosamente"
                  deleted_ip:
                    type: string
                    description: IP que fue eliminada.
                    example: "192.168.1.1"
                  remaining_ips:
                    type: integer
                    description: Número de IPs restantes en la lista.
                    example: 4
        "400":
          $ref: "#/components/responses/BadRequestError"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "404":
          $ref: "#/components/responses/NotFoundError"
        "500":
          $ref: "#/components/responses/InternalServerError"
      security:
        - ApiKeyAuth: []

  /api-keys:
    get:
      tags:
        - Gestión de API Keys
      summary: Listar API keys
      description: |
        Obtiene la lista del id y la fecha de creación de todas las API keys asociadas a la cuenta del usuario.
      security:
        - ApiKeyAuth: []
      responses:
        "200":
          description: Lista de API keys obtenida exitosamente.
          content:
            application/json:
              schema:
                type: object
                properties:
                  api_keys:
                    type: array
                    description: Lista de API keys de la cuenta
                    items:
                      $ref: "#/components/schemas/ApiKeyInfo"
              examples:
                Success:
                  summary: Respuesta exitosa
                  value:
                    api_keys:
                      - id: "ak_1234567890abcdef"
                        created_at: "2024-01-15T10:30:00Z"
                      - id: "ak_0987654321fedcba"
                        created_at: "2024-01-10T14:20:00Z"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "404":
          $ref: "#/components/responses/NotFoundError"
        "500":
          $ref: "#/components/responses/InternalServerError"
    post:
      tags:
        - Gestión de API Keys
      summary: Crear nueva API key
      description: |
        Crea una nueva API key para la cuenta del usuario.
        La API key se genera automáticamente y se retorna una sola vez.
      security:
        - ApiKeyAuth: []
      requestBody:
        description: Datos para crear la nueva API key
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - id
              properties:
                id:
                  type: string
                  description: Identificador único para la API key
                  example: "my-api-key-1"
            examples:
              CreateApiKey:
                summary: Crear nueva API key
                value:
                  id: "my-api-key-1"
      responses:
        "201":
          description: API key creada exitosamente.
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                    description: ID único de la API key
                    example: "ak_1234567890abcdef"
                  api_key:
                    type: string
                    description: La API key generada (solo se muestra una vez)
                    example: "treb_sk_live_1234567890abcdef1234567890abcdef1234567890abcdef"
                  created_at:
                    type: string
                    format: date-time
                    description: Fecha y hora de creación
                    example: "2024-01-15T10:30:00Z"
              examples:
                Success:
                  summary: API key creada
                  value:
                    id: "ak_1234567890abcdef"
                    api_key: "treb_sk_live_1234567890abcdef1234567890abcdef1234567890abcdef"
                    created_at: "2024-01-15T10:30:00Z"
        "400":
          $ref: "#/components/responses/BadRequestError"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "409":
          $ref: "#/components/responses/ConflictError"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /api-keys/{apiKeyId}:
    delete:
      tags:
        - Gestión de API Keys
      summary: Eliminar API key
      description: |
        Elimina una API key específica de la cuenta del usuario.
        La eliminación es inmediata y no se puede deshacer.
        Se puede autenticar con cualquier API key válida de la cuenta.
      security:
        - ApiKeyAuth: []
      parameters:
        - name: apiKeyId
          in: path
          required: true
          description: ID de la API key a eliminar
          schema:
            type: string
            example: "ak_1234567890abcdef"
      responses:
        "200":
          description: API key eliminada exitosamente.
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    example: "API key eliminada exitosamente"
              examples:
                Success:
                  summary: API key eliminada
                  value:
                    message: "API key eliminada exitosamente"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "404":
          $ref: "#/components/responses/NotFoundError"
        "500":
          $ref: "#/components/responses/InternalServerError"

  /v2/retention-policy:
    get:
      tags:
        - Gestión de Política de Retención
      summary: Obtener política de retención actual
      description: |
        Obtiene la política de retención de datos configurada para la cuenta.
        Si no hay política configurada, retorna la política por defecto.
      security:
        - ApiKeyAuth: []
      responses:
        "200":
          description: Política de retención obtenida exitosamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/RetentionPolicy"
              example:
                retention_days: 30
        "401":
          description: No autorizado. API key inválida o faltante.
        "500":
          description: Error interno del servidor.

    post:
      tags:
        - Gestión de Política de Retención
      summary: Crear política de retención
      description: |
        Crea una nueva política de retención de datos para la cuenta.
        Si ya existe una política, retorna un error.
      security:
        - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/RetentionPolicyRequest"
            example:
              retention_days: 30
      responses:
        "201":
          description: Política de retención creada exitosamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/RetentionPolicy"
              example:
                retention_days: 30
        "400":
          description: |
            Solicitud inválida. Posibles causas:
            - retention_days fuera del rango permitido (1-3650)
            - Ya existe una política de retención
        "401":
          description: No autorizado. API key inválida o faltante.
        "500":
          description: Error interno del servidor.

    put:
      tags:
        - Gestión de Política de Retención
      summary: Actualizar política de retención
      description: |
        Actualiza la política de retención de datos existente para la cuenta.
        Si no existe una política, la crea.
      security:
        - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/RetentionPolicyRequest"
            example:
              retention_days: 60
      responses:
        "200":
          description: Política de retención actualizada exitosamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/RetentionPolicy"
              example:
                retention_days: 60
        "400":
          description: |
            Solicitud inválida. Posibles causas:
            - retention_days fuera del rango permitido (1-3650)
        "401":
          description: No autorizado. API key inválida o faltante.
        "500":
          description: Error interno del servidor.

    delete:
      tags:
        - Gestión de Política de Retención
      summary: Eliminar política de retención
      description: |
        Elimina la política de retención de datos de la cuenta.
        Después de esta operación, se aplicará la política por defecto del sistema.
      security:
        - ApiKeyAuth: []
      responses:
        "200":
          description: Política de retención eliminada exitosamente.
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    example: "Política de retención eliminada exitosamente"
        "401":
          description: No autorizado. API key inválida o faltante.
        "404":
          $ref: "#/components/responses/NotFoundError"
        "500":
          description: Error interno del servidor.

  /v2/webhooks:
    get:
      tags:
        - Gestión de Webhooks
      summary: Listar webhooks
      description: |
        Obtiene la lista de webhooks configurados para tu cuenta. Cada webhook define una URL de destino,
        eventos suscritos y metadatos para la firma de seguridad.
      security:
        - ApiKeyAuth: []
      responses:
        "200":
          description: Lista de webhooks obtenida exitosamente.
          content:
            application/json:
              schema:
                type: object
                properties:
                  webhooks:
                    type: array
                    items:
                      $ref: "#/components/schemas/WebhookGet"
              examples:
                Success:
                  summary: Respuesta exitosa
                  value:
                    - id: "wh_123"
                      url: "https://example.com/webhooks/trebol"
                      events: ["verification.v2.created"]
                      status: "enabled"
                      description: "Webhook principal de producción"
                      created_at: "2025-08-20T10:00:00Z"
                      updated_at: "2025-08-20T10:00:00Z"
        "401":
          description: No autorizado - API key inválida.
        "500":
          description: Error interno del servidor.
    post:
      tags:
        - Gestión de Webhooks
      summary: Crear webhook
      description: |
        Crea un nuevo webhook para tu cuenta. Por seguridad, el secreto solo se muestra una vez en la creación.
      security:
        - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/WebhookCreate"
            examples:
              CreateWebhook:
                summary: Crear webhook con eventos por defecto
                value:
                  url: "https://example.com/webhooks/trebol"
                  events:
                    ["verification.v2.created", "verification.v2.finished"]
                  description: "Webhook principal de producción"
      responses:
        "201":
          description: Webhook creado exitosamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Webhook"
              examples:
                Success:
                  summary: Webhook creado
                  value:
                    id: "wh_123"
                    url: "https://example.com/webhooks/trebol"
                    events:
                      ["verification.v2.created", "verification.v2.finished"]
                    status: "enabled"
                    description: "Webhook principal de producción"
                    secret: "whsec_XXXXXXXXXXXXXXXXXXXXXXXX"
                    created_at: "2025-08-20T10:00:00Z"
                    updated_at: "2025-08-20T10:00:00Z"
        "400":
          description: Datos de entrada inválidos.
        "401":
          description: No autorizado - API key inválida.
        "500":
          description: Error interno del servidor.

  /v2/webhooks/{webhookId}:
    get:
      tags:
        - Gestión de Webhooks
      summary: Obtener webhook
      description: Obtiene la configuración de un webhook específico.
      security:
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/webhookIdParam"
      responses:
        "200":
          description: Webhook obtenido exitosamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WebhookGet"
              examples:
                Success:
                  value:
                    id: "wh_123"
                    url: "https://example.com/webhooks/trebol"
                    events: ["verification.v2.created"]
                    status: "enabled"
                    description: "Webhook principal de producción"
                    created_at: "2025-08-20T10:00:00Z"
                    updated_at: "2025-08-20T10:00:00Z"
        "401":
          description: No autorizado
        "404":
          description: Webhook no encontrado
    put:
      tags:
        - Gestión de Webhooks
      summary: Actualizar webhook
      description: Actualiza la URL, eventos, descripción o estado activo del webhook.
      security:
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/webhookIdParam"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/WebhookUpdate"
            examples:
              UpdateWebhook:
                value:
                  url: "https://example.com/webhooks/trebol-v2"
                  events:
                    ["verification.v2.created", "verification.v2.finished"]
                  active: true
      responses:
        "200":
          description: Webhook actualizado exitosamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WebhookGet"
        "400":
          description: Datos de entrada inválidos
        "401":
          description: No autorizado
        "404":
          description: Webhook no encontrado
    delete:
      tags:
        - Gestión de Webhooks
      summary: Eliminar webhook
      description: Elimina un webhook específico.
      security:
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/webhookIdParam"
      responses:
        "200":
          description: Webhook eliminado exitosamente.
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    example: "Webhook eliminado exitosamente"
        "401":
          description: No autorizado
        "404":
          description: Webhook no encontrado

  /v2/custom-item-types:
    post:
      operationId: crearTipoItemPersonalizado
      tags:
        - Tipos de Ítem Personalizados
      summary: Crear un tipo de ítem personalizado
      description: |
        Crea un nuevo tipo de ítem personalizado. El `name` debe empezar con `cit_` y no puede contener espacios.
      security:
        - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateCustomItemTypeRequest"
            examples:
              WithAutoImprove:
                summary: Con mejora automática (por defecto)
                value:
                  name: "cit_contrato_arrendamiento"
                  user_input: "Este documento es un contrato de arrendamiento inmobiliario firmado ante notario."
                  friendly_name: "Contrato de arrendamiento"
              WithoutAutoImprove:
                summary: Sin mejora automática
                value:
                  name: "cit_certificado_estudios"
                  user_input: "Clasifica este documento como certificado de estudios solo si corresponde a un certificado emitido por una institución educativa."
                  friendly_name: "Certificado de estudios"
                  auto_improve: false
      responses:
        "201":
          description: Tipo de ítem personalizado creado exitosamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CustomItemTypeResponse"
        "400":
          description: |
            Solicitud inválida. Posibles causas:
            - `name`, `user_input` o `friendly_name` faltante o inválido.
            - `name` no empieza con `cit_` o contiene espacios.
            - `friendly_name` fuera del rango de 2 a 255 caracteres.
        "401":
          description: No autorizado. API key inválida o faltante.
        "409":
          description: "Conflicto: `name` ya existe en la cuenta o está reservado por un tipo global (activo o archivado)."
    get:
      operationId: listarTiposItemPersonalizados
      tags:
        - Tipos de Ítem Personalizados
      summary: Listar tipos de ítem personalizados
      description: |
        Devuelve los tipos no eliminados de la cuenta (activos y archivados) y los tipos globales activos, con sus procesos.
        Los tipos globales incluyen `is_global: true` y son de solo lectura para tu cuenta.
        Consulta el [catálogo de ítems globales](/guia-devs/uso-kyb/todos-paises/items-globales).
        Ordenados por fecha de creación descendente. Tamaño de página por defecto: 10,
        ajustable con `limit` hasta un máximo de 100.
        Las respuestas GET incluyen `user_input` y `json_schema` en cada proceso.
      security:
        - ApiKeyAuth: []
      parameters:
        - name: next
          in: query
          schema:
            type: string
          description: Token de cursor para obtener la siguiente página.
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 10
          description: |
            Cantidad de tipos por página. Los valores mayores a 100 se ajustan a 100
            (no producen error). Útil para recuperar todos los tipos en menos llamadas.
      responses:
        "200":
          description: Lista de tipos de ítem personalizados obtenida exitosamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CustomItemTypeReadListResponse"
        "400":
          description: "Token de cursor inválido, o `limit` no es un entero positivo."
        "401":
          description: No autorizado. API key inválida o faltante.

  /v2/custom-item-types/{id}:
    get:
      operationId: obtenerTipoItemPersonalizado
      tags:
        - Tipos de Ítem Personalizados
      summary: Obtener un tipo de ítem personalizado
      description: |
        Devuelve un tipo con todos sus procesos. Misma estructura que un elemento individual del listado.
        Incluye tipos de tu cuenta (activos y archivados) y tipos globales activos, identificados con `is_global: true`.
        Los tipos globales son de solo lectura. Los globales archivados, los eliminados y los tipos de otras cuentas producen 404.
        Consulta el [catálogo de ítems globales](/guia-devs/uso-kyb/todos-paises/items-globales).
      security:
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/customItemTypeId"
      responses:
        "200":
          description: Tipo de ítem personalizado obtenido exitosamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CustomItemTypeReadResponse"
        "401":
          description: No autorizado. API key inválida o faltante.
        "404":
          description: Tipo no encontrado, eliminado, global archivado o perteneciente a otra cuenta.
    patch:
      operationId: actualizarTipoItemPersonalizado
      tags:
        - Tipos de Ítem Personalizados
      summary: Actualizar un tipo de ítem personalizado
      description: |
        Los tipos globales son de solo lectura; intentar actualizarlos devuelve 403.
        Actualiza campos del tipo. Debes enviar al menos un campo.
        Si todos los campos ya coinciden con los valores actuales, no se ejecuta ningún UPDATE y `updated_at` no cambia (idempotencia).
      security:
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/customItemTypeId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdateCustomItemTypeRequest"
      responses:
        "200":
          description: Tipo actualizado exitosamente. Devuelve solo campos del tipo, sin procesos.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CustomItemTypeUpdateResponse"
        "400":
          description: |
            Solicitud inválida. Posibles causas:
            - Ningún campo proporcionado, valor inválido o `name` vacío.
            - `status` con valor no permitido (solo `"active"` o `"archived"`).
            - `friendly_name` fuera del rango de 2 a 255 caracteres.
        "401":
          description: No autorizado. API key inválida o faltante.
        "403":
          description: Los tipos globales y sus procesos son de solo lectura para tu cuenta.
        "404":
          description: Tipo no encontrado (los tipos archivados sí se pueden actualizar).
        "409":
          description: "`name` colisiona con otro tipo de la cuenta o está reservado por un tipo global (activo o archivado)."
    delete:
      operationId: eliminarTipoItemPersonalizado
      tags:
        - Tipos de Ítem Personalizados
      summary: Eliminar un tipo de ítem personalizado
      description: |
        Los tipos globales son de solo lectura; intentar eliminarlos devuelve 403.
        Elimina el tipo de forma permanente junto con todos sus procesos. Es irreversible.
        Para pausar un tipo sin borrarlo (y poder reactivarlo después), usa PATCH con `status: "archived"` en lugar de DELETE.
      security:
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/customItemTypeId"
      responses:
        "200":
          description: Tipo eliminado exitosamente.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  data:
                    type: object
                    properties:
                      id:
                        type: string
                        example: "cit_abc123"
        "401":
          description: No autorizado. API key inválida o faltante.
        "403":
          description: Los tipos globales y sus procesos son de solo lectura para tu cuenta.
        "404":
          description: Tipo no encontrado o ya eliminado.

  /v2/custom-item-types/{id}/processes:
    post:
      operationId: crearProcesoTipoItemPersonalizado
      tags:
        - Tipos de Ítem Personalizados
      summary: Agregar un proceso a un tipo de ítem personalizado
      description: |
        Los tipos globales son de solo lectura; intentar agregarles procesos devuelve 403.
        Agrega un proceso de validación o extracción a un tipo existente. Hasta 5 procesos de extracción y 20 de validación por tipo.
        En procesos de extracción sin `json_schema`, `auto_improve` debe enviarse como `true`; enviarlo como `false` devuelve 400.
        Si se envía `json_schema`, `auto_improve` se establece en `false` automáticamente; enviarlo como `true` devuelve 400.
      security:
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/customItemTypeId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateCustomItemTypeProcessRequest"
            examples:
              Extraction:
                summary: Proceso de extracción con auto_improve
                value:
                  process_type: "extraction"
                  process_reference: "extraer_montos"
                  user_input: "Extrae todos los montos monetarios del contrato, incluyendo renta mensual y depósito."
                  auto_improve: true
              ExtractionWithSchema:
                summary: Proceso de extracción con json_schema propio
                value:
                  process_type: "extraction"
                  process_reference: "extraer_personas"
                  user_input: "Extrae todas las personas mencionadas en el documento con su nombre completo y rol."
                  json_schema:
                    type: "object"
                    required:
                      - "persons"
                    properties:
                      persons:
                        type: "array"
                        description: "Lista de todas las personas mencionadas en el documento."
                        items:
                          type: "object"
                          required:
                            - "name"
                            - "role"
                          properties:
                            name:
                              type: "string"
                              description: "Nombre completo de la persona mencionada en el documento."
                            role:
                              type: ["string", "null"]
                              description: "Rol, cargo o calidad con la que la persona aparece en el documento. Usa null si no se especifica."
              Validation:
                summary: Proceso de validación con failure_policy
                value:
                  process_type: "validation"
                  process_reference: "validar_firmas"
                  user_input: "Verifica que el contrato contenga las firmas de ambas partes y del notario público."
                  failure_policy: "hard_stop"
      responses:
        "201":
          description: Proceso creado exitosamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CustomItemTypeProcessResponse"
        "400":
          description: |
            Solicitud inválida. Posibles causas:
            - Campos requeridos faltantes o inválidos.
            - `auto_improve: false` en extracción sin `json_schema`.
            - `auto_improve: true` en extracción con `json_schema`.
            - `json_schema` enviado en un proceso que no es de extracción.
            - `json_schema` con formato inválido.
            - `failure_policy` enviado en un proceso que no es de validación.
        "401":
          description: No autorizado. API key inválida o faltante.
        "403":
          description: Los tipos globales y sus procesos son de solo lectura para tu cuenta.
        "404":
          description: Tipo padre no encontrado o eliminado.
        "409":
          description: |
            Conflicto. Posibles causas:
            - `process_reference` ya existe en este tipo.
            - `user_input` idéntico ya en uso en otro proceso del mismo tipo.
            - Se alcanzó el límite de procesos del tipo (5 de extracción o 20 de validación).

  /v2/custom-item-types/{id}/processes/{processId}:
    get:
      operationId: obtenerProcesoTipoItemPersonalizado
      tags:
        - Tipos de Ítem Personalizados
      summary: Obtener un proceso de un tipo de ítem personalizado
      description: |
        Devuelve un proceso con su versión activa, incluyendo `user_input` y `json_schema`.
        Puedes consultar procesos de tipos de tu cuenta (activos o archivados) y de tipos globales activos.
        El tipo padre y el proceso deben existir y no estar eliminados. La versión activa debe existir y tener `user_input` no nulo.
        Los tipos globales archivados producen 404.
      security:
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/customItemTypeId"
        - $ref: "#/components/parameters/processId"
      responses:
        "200":
          description: Proceso obtenido exitosamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CustomItemTypeProcessDetailResponse"
        "401":
          description: No autorizado. API key inválida o faltante.
        "404":
          description: Tipo padre no encontrado, eliminado o global archivado; proceso no encontrado; o versión activa inválida.
    patch:
      operationId: actualizarProcesoTipoItemPersonalizado
      tags:
        - Tipos de Ítem Personalizados
      summary: Actualizar un proceso de un tipo de ítem personalizado
      description: |
        Los procesos de tipos globales son de solo lectura; intentar actualizarlos devuelve 403.
        Actualiza un proceso. Debes enviar al menos un campo. `process_type` y `id` no se pueden cambiar.
        Cuando el PATCH modifica `user_input`, se crea una nueva versión del proceso que pasa a ser la activa.
      security:
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/customItemTypeId"
        - $ref: "#/components/parameters/processId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdateCustomItemTypeProcessRequest"
            examples:
              RotateUserInput:
                summary: Rotar user_input con mejora automática
                value:
                  user_input: "Extrae todos los montos monetarios del contrato: renta mensual, depósito, penalización por mora y total anual."
                  auto_improve: true
              DeactivateProcess:
                summary: Desactivar un proceso
                value:
                  is_active: false
      responses:
        "200":
          description: Proceso actualizado exitosamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CustomItemTypeProcessResponse"
        "400":
          description: |
            Solicitud inválida. Posibles causas:
            - `failure_policy` con valor no nulo en un proceso que no es de validación.
            - `json_schema` enviado en un proceso que no es de extracción, o con formato inválido.
            - `auto_improve: true` enviado junto con `json_schema`.
        "401":
          description: No autorizado. API key inválida o faltante.
        "403":
          description: Los tipos globales y sus procesos son de solo lectura para tu cuenta.
        "404":
          description: Tipo padre o proceso no encontrado.
        "409":
          description: |
            Conflicto. Posibles causas:
            - `process_reference` colisiona con otro proceso del mismo tipo.
            - `user_input` idéntico ya usado en otro proceso del mismo tipo.
            - Se intentó pausar (`is_active: false`) el proceso de clasificación, que no se puede pausar.
    delete:
      operationId: eliminarProcesoTipoItemPersonalizado
      tags:
        - Tipos de Ítem Personalizados
      summary: Eliminar un proceso de un tipo de ítem personalizado
      description: |
        Los procesos de tipos globales son de solo lectura; intentar eliminarlos devuelve 403.
        Elimina permanentemente un proceso de validación o extracción. El proceso de clasificación no se puede eliminar; intentarlo devuelve 409. Para modificar sus instrucciones, usa PATCH sobre el proceso.
      security:
        - ApiKeyAuth: []
      parameters:
        - $ref: "#/components/parameters/customItemTypeId"
        - $ref: "#/components/parameters/processId"
      responses:
        "200":
          description: Proceso eliminado exitosamente.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  data:
                    type: object
                    properties:
                      id:
                        type: string
                        example: "ccp_ghi789"
        "401":
          description: No autorizado. API key inválida o faltante.
        "403":
          description: Los tipos globales y sus procesos son de solo lectura para tu cuenta.
        "404":
          description: Tipo padre no encontrado, o proceso no encontrado / ya eliminado.
        "409":
          description: No se puede eliminar el proceso de clasificación.

  /companies/{etiqueta}/details:
    get:
      tags:
        - Leer información de la empresa v1
      summary: Obtener estatutos de las actas por la Etiqueta
      description: Obtener información detallada de los estatutos e información fiscal sobre una empresa específica usando su etiqueta.
      parameters:
        - $ref: "#/components/parameters/etiquetaParam"
      responses:
        "200":
          description: Detalles de la empresa recuperados exitosamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CompanyDetailsResponse"
              examples:
                Success:
                  summary: Respuesta exitosa
                  value:
                    fields:
                      business_name:
                        value: "TREBOL OPCO S.A. DE C.V."
                        businessType: "company"
                        sourceLines: ["Acta #123", "SIGER"]
                      tax_id:
                        value: "SAG160927GIA"
                    verification:
                      id: "c8dc41fc-c477-404e-aff7-b9074f86d6d1"
                      tag: "etiqueta"
                      status: "pending"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "404":
          $ref: "#/components/responses/NotFoundError"
        "500":
          $ref: "#/components/responses/InternalServerError"
      security:
        - ApiKeyAuth: []

  /companies/{etiqueta}/documents:
    get:
      tags:
        - Leer información de la empresa v1
      summary: Obtener documentos de la empresa
      description: Obtener documentos que se han subido por el cliente o que encontrado en portales oficiales del gobierno. Se usa la etiqueta asignada para obtener la información.
      parameters:
        - in: path
          name: etiqueta
          required: true
          description: La etiqueta del cliente.
          schema:
            type: string
      responses:
        "200":
          description: Documentos de la empresa recuperados exitosamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CompanyDocumentsResponse"
              examples:
                Success:
                  summary: Respuesta exitosa
                  value:
                    documents:
                      - label: "Constancia de situación fiscal"
                        url: "https://..."
                      - label: "Acta constitutiva"
                        url: "https://..."
                    verification:
                      id: "c8dc41fc-c477-404e-aff7-b9074f86d6d1"
                      tag: "etiqueta"
                      status: "pending"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "404":
          $ref: "#/components/responses/NotFoundError"
        "500":
          $ref: "#/components/responses/InternalServerError"
      security:
        - ApiKeyAuth: []

  /companies/{etiqueta}/people:
    get:
      tags:
        - Leer información de la empresa v1
      summary: Obtener apoderados y representantes legales de la empresa de las actas por la Etiqueta
      description: Obtener la lista de apoderados y representantes legales analizados de la empresa. Se obtiene la lista de apoderados, sus roles, facultades, vigencias, limitaciones, y tipos de firma.
      parameters:
        - in: path
          name: etiqueta
          required: true
          description: La etiqueta del cliente.
          schema:
            type: string
      responses:
        "200":
          description: Signatarios de la empresa recuperados exitosamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CompanyPeopleResponse"
              examples:
                Success:
                  summary: Respuesta exitosa
                  value:
                    data:
                      key_people:
                        - names: "Juan Pérez"
                          role: "apoderado"
                          powers: { overall: "has_power" }
                      full_list:
                        - names: "Juan Pérez"
                          role: "apoderado"
                        - names: "María Gómez"
                          role: "representante legal"
                      board_members:
                        - name: "Ana López"
                          event: "addition"
                    verification:
                      id: "c8dc41fc-c477-404e-aff7-b9074f86d6d1"
                      tag: "etiqueta"
                      status: "pending"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "404":
          $ref: "#/components/responses/NotFoundError"
        "500":
          $ref: "#/components/responses/InternalServerError"
      security:
        - ApiKeyAuth: []

  /companies/{etiqueta}/shareholders:
    get:
      tags:
        - Leer información de la empresa v1
      summary: Obtener accionistas de las actas de la empresa por la Etiqueta
      description: Obtener la lista de accionistas asociados con una empresa específica y la documentación que se sube.
      parameters:
        - in: path
          name: etiqueta
          required: true
          description: La etiqueta del cliente.
          schema:
            type: string
      responses:
        "200":
          description: Accionistas de la empresa recuperados exitosamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CompanyShareholdersResponse"
              examples:
                Success:
                  summary: Respuesta exitosa
                  value:
                    shareholders:
                      - name: "ACME LLC"
                        share_percentage: 60
                      - name: "Juan Pérez"
                        share_percentage: 40
                    capital:
                      total_value: 1000000
                      currency: "MXN"
                    source:
                      document: "acta_constitutiva"
                    shareholders_unavailable_reason: null
                    business_type: "SOCIEDAD ANONIMA DE CAPITAL VARIABLE"
                    verification:
                      id: "c8dc41fc-c477-404e-aff7-b9074f86d6d1"
                      tag: "etiqueta"
                      status: "pending"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "404":
          $ref: "#/components/responses/NotFoundError"
        "500":
          $ref: "#/components/responses/InternalServerError"
      security:
        - ApiKeyAuth: []

  /companies/{etiqueta}/sources:
    get:
      tags:
        - Leer información de la empresa v1
      summary: Obtener la informacion de la prevalidacion de documentos asosciados a una empresa
      description: Obtener la información de la preevaluación de documentos relacionados con una empresa específica.
      parameters:
        - in: path
          name: etiqueta
          required: true
          description: La etiqueta del cliente.
          schema:
            type: string
      responses:
        "200":
          description: Fuentes de pre-evaluación de documentos recuperadas exitosamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CompanySourcesResponse"
              examples:
                Success:
                  summary: Respuesta exitosa
                  value:
                    data:
                      - type: "csf_mx"
                        label: "Constancia SAT"
                        item_id: 123
                        status: "complete"
                      - type: "ac_mx"
                        label: "Acta constitutiva"
                        item_id: 456
                        status: "needs-review"
                    verification:
                      id: "c8dc41fc-c477-404e-aff7-b9074f86d6d1"
                      tag: "etiqueta"
                      status: "pending"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "404":
          $ref: "#/components/responses/NotFoundError"
        "500":
          $ref: "#/components/responses/InternalServerError"
      security:
        - ApiKeyAuth: []

  /verifications/{verification-id}/details:
    get:
      tags:
        - Leer información de la empresa v1
      summary: Obtener estatutos de las actas por el ID de Verificacion
      description: Obtener información detallada sobre los estatutos e información fiscal de la empresa usando el id de la verificación.
      parameters:
        - $ref: "#/components/parameters/verificationIdParam"
      responses:
        "200":
          description: Detalles de la verificación recuperados exitosamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CompanyDetailsResponse"
              examples:
                Success:
                  summary: Respuesta exitosa
                  value:
                    fields:
                      business_name:
                        value: "TREBOL OPCO S.A. DE C.V."
                      tax_id:
                        value: "SAG160927GIA"
                    verification:
                      id: "c8dc41fc-c477-404e-aff7-b9074f86d6d1"
                      tag: "etiqueta"
                      status: "pending"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "404":
          $ref: "#/components/responses/NotFoundError"
        "500":
          $ref: "#/components/responses/InternalServerError"
      security:
        - ApiKeyAuth: []

  /verifications/{verification-id}/documents:
    get:
      tags:
        - Leer información de la empresa v1
      summary: Obtener documentos de la empresa por id de verificacion
      description: Obtener documentos relacionados con una verificación específica usando el id de la verificación.
      parameters:
        - in: path
          name: verification-id
          required: true
          description: El ID de la verificación.
          schema:
            type: string
      responses:
        "200":
          description: Documentos de la verificación recuperados exitosamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CompanyDocumentsResponse"
              examples:
                Success:
                  summary: Respuesta exitosa
                  value:
                    documents:
                      - label: "Constancia de situación fiscal"
                        url: "https://..."
                      - label: "Acta constitutiva"
                        url: "https://..."
                    verification:
                      id: "c8dc41fc-c477-404e-aff7-b9074f86d6d1"
                      tag: "etiqueta"
                      status: "pending"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "404":
          $ref: "#/components/responses/NotFoundError"
        "500":
          $ref: "#/components/responses/InternalServerError"
      security:
        - ApiKeyAuth: []

  /verifications/{verification-id}/people:
    get:
      tags:
        - Leer información de la empresa v1
      summary: Obtener apoderados y representates legales de la empresa de las actas por el ID de Verificacion
      description: Obtener la lista de apoderados y representates legales de la empresa usando el id de la verificación.
      parameters:
        - in: path
          name: verification-id
          required: true
          description: El ID de la verificación.
          schema:
            type: string
      responses:
        "200":
          description: Signatarios de la verificación recuperados exitosamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CompanyPeopleResponse"
              examples:
                Success:
                  summary: Respuesta exitosa
                  value:
                    data:
                      key_people:
                        - names: "Juan Pérez"
                          role: "apoderado"
                      full_list:
                        - names: "Juan Pérez"
                          role: "apoderado"
                      board_members:
                        - name: "Ana López"
                          event: "addition"
                    verification:
                      id: "c8dc41fc-c477-404e-aff7-b9074f86d6d1"
                      tag: "etiqueta"
                      status: "pending"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "404":
          $ref: "#/components/responses/NotFoundError"
        "500":
          $ref: "#/components/responses/InternalServerError"
      security:
        - ApiKeyAuth: []

  /verifications/{verification-id}/shareholders:
    get:
      tags:
        - Leer información de la empresa v1
      summary: Obtener accionistas de la empresa de las actas por el ID de Verificacion
      description: Obtener la lista de accionistas asociados con una empresa usando el id de la verificación.
      parameters:
        - in: path
          name: verification-id
          required: true
          description: El ID de la verificación.
          schema:
            type: string
      responses:
        "200":
          description: Accionistas de la verificación recuperados exitosamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CompanyShareholdersResponse"
              examples:
                Success:
                  summary: Respuesta exitosa
                  value:
                    shareholders:
                      - name: "ACME LLC"
                        share_percentage: 60
                      - name: "Juan Pérez"
                        share_percentage: 40
                    capital:
                      total_value: 1000000
                      currency: "MXN"
                    source:
                      document: "acta_constitutiva"
                    shareholders_unavailable_reason: null
                    business_type: "SOCIEDAD ANONIMA DE CAPITAL VARIABLE"
                    verification:
                      id: "c8dc41fc-c477-404e-aff7-b9074f86d6d1"
                      tag: "etiqueta"
                      status: "pending"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "404":
          $ref: "#/components/responses/NotFoundError"
        "500":
          $ref: "#/components/responses/InternalServerError"
      security:
        - ApiKeyAuth: []

  /verifications/{verification-id}/sources:
    get:
      tags:
        - Leer información de la empresa v1
      summary: Obtener datos de prevalidacion de documentos
      description: Obtener fuentes para la pre-evaluación de documentos relacionados con una  empresa usando el id de la verificación.
      parameters:
        - in: path
          name: verification-id
          required: true
          description: El ID de la verificación.
          schema:
            type: string
      responses:
        "200":
          description: Fuentes de pre-evaluación de documentos recuperadas exitosamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CompanySourcesResponse"
              examples:
                Success:
                  summary: Respuesta exitosa
                  value:
                    data:
                      - type: "csf_mx"
                        label: "Constancia SAT"
                        item_id: 123
                        status: "complete"
                    verification:
                      id: "c8dc41fc-c477-404e-aff7-b9074f86d6d1"
                      tag: "etiqueta"
                      status: "pending"
        "401":
          $ref: "#/components/responses/UnauthorizedError"
        "404":
          $ref: "#/components/responses/NotFoundError"
        "500":
          $ref: "#/components/responses/InternalServerError"
      security:
        - ApiKeyAuth: []

components:
  parameters:
    etiquetaParam:
      name: etiqueta
      in: path
      required: true
      description: La etiqueta única que identifica la empresa dentro de tu sistema interno
      schema:
        type: string
    verificationIdParam:
      name: verification-id
      in: path
      required: true
      description: El ID único de la verificación
      schema:
        type: string
    webhookIdParam:
      name: webhookId
      in: path
      required: true
      description: ID único del webhook
      example: "wh_123"
      schema:
        type: string
    customItemTypeId:
      name: id
      in: path
      required: true
      description: Identificador único del tipo de ítem personalizado (ej. `cit_abc123`).
      schema:
        type: string
      example: "cit_abc123"
    processId:
      name: processId
      in: path
      required: true
      description: Identificador único del proceso (ej. `ccp_def456`).
      schema:
        type: string
      example: "ccp_def456"
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
  responses:
    BadRequestError:
      description: Datos de entrada inválidos
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
          examples:
            ValidationError:
              summary: Error de validación
              value:
                success: false
                message: "Validation failed: 'items' is required"
                code: VALIDATION_ERROR
                timestamp: "2025-01-01T12:34:56.000Z"
            ItemsNotProvided:
              summary: items_not_provided
              value:
                success: false
                message: "Please provide a valid items array or a flow id in your request"
                code: items_not_provided
                timestamp: "2025-01-01T12:34:56.000Z"
            InvalidItemType:
              summary: invalid_item_type
              value:
                success: false
                message: "The generic item type is not supported"
                code: invalid_item_type
                timestamp: "2025-01-01T12:34:56.000Z"
            InvalidItemOptionsFileUrl:
              summary: invalid_item_options_file_url
              value:
                success: false
                message: "The specified file_url is invalid. Ensure it is public and downloadable."
                code: invalid_item_options_file_url
                timestamp: "2025-01-01T12:34:56.000Z"
            InvalidItemOptionsFilePassword:
              summary: invalid_item_options_file_password
              value:
                success: false
                message: "The file_password option must be a non-empty string."
                code: invalid_item_options_file_password
                timestamp: "2025-01-01T12:34:56.000Z"
    UnauthorizedError:
      description: No autorizado
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
          examples:
            Unauthorized:
              summary: Falta API key o inválida
              value:
                success: false
                message: "Unauthorized"
                code: UNAUTHORIZED
                timestamp: "2025-01-01T12:34:56.000Z"
    NotFoundError:
      description: Recurso no encontrado
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
          examples:
            NotFound:
              summary: Recurso inexistente
              value:
                success: false
                message: "Entity not found"
                code: NOT_FOUND
                timestamp: "2025-01-01T12:34:56.000Z"
    ConflictError:
      description: Conflicto
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
          examples:
            DuplicateResource:
              summary: Recurso duplicado
              value:
                success: false
                message: "form-schema with identifier example-id already exists."
                code: DUPLICATE_RESOURCE
                timestamp: "2025-01-01T12:34:56.000Z"
    InternalServerError:
      description: Error interno del servidor
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
          examples:
            ServerError:
              summary: Error inesperado
              value:
                success: false
                message: "Internal server error"
                code: INTERNAL_SERVER_ERROR
                timestamp: "2025-01-01T12:34:56.000Z"
  examples:
    V2DetailsExample:
      summary: details
      value:
        success: true
        data:
          verification:
            id: "c8dc41fc-c477-404e-aff7-b9074f86d6d1"
            account_id: "99999999-9999-9999-9999-999999999999"
            tag: "mi-etiqueta"
            created_at: "2025-04-28T20:10:06.840Z"
            comments_legal_review: ["Nombre inconsistente en acta 2019"]
            business_name:
              { value: "TREBOL OPCO S.A. DE C.V.", validations: [] }
            flow_id: "documents-v2"
            onboarding_url: "https://onboarding.gotrebol.com/verification/c8dc41fc..."
            documents_status: "full_upload"
            created_by: "99999999-9999-9999-9999-999999999999"
            status: "pending"
            country: "mx"
            tax_id: "SAG160927GIA"
          legal:
            business_name:
              {
                value: "TREBOL OPCO S.A. DE C.V.",
                source:
                  {
                    item_id: 123,
                    item_type: "ac_mx",
                    document_url: null,
                    document_date: null,
                    document_number: null,
                    entity_name: null,
                    extra_fields: null,
                    information_source: null,
                    source_date: null,
                    subject_id: null,
                  },
              }
            business_type:
              { value: "company", source: { item_id: 123, item_type: "ac_mx" } }
            business_folio_number:
              { value: "123456", source: { item_id: 123, item_type: "ac_mx" } }
            business_duration:
              {
                value: "indefinida",
                source: { item_id: 123, item_type: "ac_mx" },
              }
            business_expiry_date: null
            business_legal_address:
              {
                value: "CDMX, México",
                source: { item_id: 123, item_type: "ac_mx" },
              }
            business_creditor_ability:
              { value: true, source: { item_id: 123, item_type: "ac_mx" } }
            business_asset_pledging:
              { value: false, source: { item_id: 123, item_type: "ac_mx" } }
            business_guarantor_ability:
              { value: true, source: { item_id: 123, item_type: "ac_mx" } }
            latest_acta_date:
              {
                value: "2024-10-12",
                source: { item_id: 123, item_type: "ac_mx" },
              }
          registration:
            has_constitutive:
              { value: true, source: { item_id: 123, item_type: "ac_mx" } }
            business_name:
              {
                value: "TREBOL OPCO S.A. DE C.V.",
                source: { item_id: 123, item_type: "ac_mx" },
              }
            acta_number:
              { value: "12,345", source: { item_id: 123, item_type: "ac_mx" } }
            notary_number:
              { value: "112", source: { item_id: 123, item_type: "ac_mx" } }
            notary_name:
              {
                value: "Lic. Pérez",
                source: { item_id: 123, item_type: "ac_mx" },
              }
            business_type:
              {
                value: "S.A. de C.V.",
                source: { item_id: 123, item_type: "ac_mx" },
              }
            folio_number:
              { value: "FN-123", source: { item_id: 123, item_type: "ac_mx" } }
            folio_date:
              {
                value: "2020-03-01",
                source: { item_id: 123, item_type: "ac_mx" },
              }
            folio_inscription_date:
              {
                value: "2020-03-15",
                source: { item_id: 123, item_type: "ac_mx" },
              }
            city:
              { value: "CDMX", source: { item_id: 123, item_type: "ac_mx" } }
            state:
              {
                value: "Ciudad de México",
                source: { item_id: 123, item_type: "ac_mx" },
              }
            registration_date:
              {
                value: "2020-03-01",
                source: { item_id: 123, item_type: "ac_mx" },
              }
          tax:
            has_constancia:
              { value: true, source: { item_id: 456, item_type: "csf_mx" } }
            business_name:
              {
                value: "TREBOL OPCO S.A. DE C.V.",
                source: { item_id: 456, item_type: "csf_mx" },
              }
            business_type:
              {
                value: "company",
                source: { item_id: 456, item_type: "csf_mx" },
              }
            business_tax_id:
              {
                value: "SAG160927GIA",
                source: { item_id: 456, item_type: "csf_mx" },
              }
            business_main_activity:
              value:
                - order: 1
                  economic_activity: "Servicios de software"
                  percentage: 100
                  date: "2024-01-01"
              source: { item_id: 456, item_type: "csf_mx" }
            business_fiscal_status:
              { value: "ACTIVO", source: { item_id: 456, item_type: "csf_mx" } }
            qr_validation:
              { value: true, source: { item_id: 456, item_type: "csf_mx" } }
            business_regime:
              {
                value: "Régimen General",
                source: { item_id: 456, item_type: "csf_mx" },
              }
            additional_data:
              value: { qr_status: "valid" }
              source: { item_id: 456, item_type: "csf_mx" }
          signatory_validation:
            full_name:
              {
                value: "Juan Pérez",
                source: { item_id: 789, item_type: "person_id" },
              }
            paternal_last_name:
              {
                value: "Pérez",
                source: { item_id: 789, item_type: "person_id" },
              }
            maternal_last_name:
              {
                value: "García",
                source: { item_id: 789, item_type: "person_id" },
              }
            document_number:
              {
                value: "INE-123",
                source: { item_id: 789, item_type: "person_id" },
              }
            validation_status:
              {
                value: "match",
                source: { item_id: 789, item_type: "person_id" },
              }
            validation_value:
              {
                value: "Juan Pérez",
                source: { item_id: 789, item_type: "person_id" },
              }
            validation_date:
              {
                value: "2025-01-15",
                source: { item_id: 789, item_type: "person_id" },
              }
            name_comparison_result:
              {
                value: "strong_match",
                source: { item_id: 789, item_type: "person_id" },
              }
            id_validation_provider:
              value:
                provider_name: "qDetect"
                provider_id: "qd-01"
                provider_details_url: "https://..."
              source: { item_id: 789, item_type: "person_id" }
          banking:
            address:
              {
                value: "Calle Falsa 123, CDMX",
                source: { item_id: 901, item_type: "bank_statement" },
              }
            entity_name:
              {
                value: "BBVA",
                source: { item_id: 901, item_type: "bank_statement" },
              }
            document_date:
              {
                value: "2024-12-01",
                source: { item_id: 901, item_type: "bank_statement" },
              }
            additional_data:
              value: { rfc: "SAG160927GIA", clabe_number: "012345678901234567" }
              source: { item_id: 901, item_type: "bank_statement" }
          address:
            business_fiscal_address:
              {
                value: "CDMX, México",
                source: { item_id: 456, item_type: "csf_mx" },
              }
            business_fiscal_address_disaggregated:
              value:
                street_type: "CALLE"
                street_name: "Falsa"
                external_number: "123"
                internal_number: "2"
                neighborhood: "Centro"
                district: "Cuauhtémoc"
                state: "CDMX"
                post_code: "06000"
              source: { item_id: 456, item_type: "csf_mx" }
            business_comercial_address:
              {
                value: "CDMX, México",
                source: { item_id: 901, item_type: "bank_statement" },
              }
        meta:
          section: "details"
          verification:
            id: "c8dc41fc-c477-404e-aff7-b9074f86d6d1"
            tag: "mi-etiqueta"
            status: "pending"
    V2ShareholdersExample:
      summary: shareholders
      value:
        success: true
        data:
          shareholders:
            - id: 1
              currency: "MXN"
              fixed_shares: 1000
              fixed_value: 100000
              id_number: "ABC123456"
              id_type: "INE"
              name: "Juan Pérez"
              nationality: "MX"
              total_shares: 1500
              total_value: 150000
              type: "individual"
              variable_shares: 500
              variable_value: 50000
              share_percentage: 60
              identity: {}
              fiscal: {}
              address: {}
          capital:
            fixed_value: 100000
            fixed_shares: 1000
            fixed_value_currency: "MXN"
            variable_value: 50000
            variable_shares: 500
            variable_value_currency: "MXN"
            total_value: 150000
            total_shares: 1500
            total_value_currency: "MXN"
          source:
            item_id: 321
            subject_id: null
            item_type: "ac_mx"
            document_url: null
            document_date: "2024-10-12"
            document_number: "ACT-123"
            entity_name: "TREBOL OPCO S.A. DE C.V."
            extra_fields:
              folio_acta_number: "ACT-123"
              folio_number: "FN-123"
              folio_date: "2024-10-12"
              folio_inscription_date: "2024-10-20"
              notary_number: "112"
              notary_name: "Lic. Pérez"
              notary_city: "CDMX"
              notary_state: "CDMX"
              folio_data_source:
                folio_number_source: "ac_mx"
                folio_date_source: "ac_mx"
            information_source: "acta_constitutiva"
            source_date: "2024-10-12"
          shareholders_unavailable_reason: null
          business_type: "SOCIEDAD ANONIMA DE CAPITAL VARIABLE"
        meta:
          section: "shareholders"
          verification:
            id: "c8dc41fc-c477-404e-aff7-b9074f86d6d1"
            tag: "mi-etiqueta"
            status: "pending"
    V2PeopleExample:
      summary: people
      value:
        success: true
        data:
          key_people:
            - names: "RODRIGUEZ MARTINEZ CARLOS ALBERTO"
              id_number: "ROMC850315HDFRRS07"
              id_type: "curp"
              type: "person"
              gender: "HOMBRE"
              nationality: "MEXICO"
              iso_country_code: "MX"
              birth_date: "1985-03-15"
              birth_entity: "DISTRITO FEDERAL"
              roles:
                - role_name: "apoderado"
                  group_name: "proxies"
                  event: "addition"
                  duration: 0
                  powers: []
                  source: { item_id: 45678, item_type: "ac_mx" }
              identity:
                person_id:
                  description: "ine_mx - ROMC850315HDFRRS07"
                  address: "AV INSURGENTES SUR 1647 COL DEL VALLE BENITO JUAREZ, CDMX"
                  document_date: "2030-06-30"
                  issued_date: "2022-01-01T00:00:00Z"
                  due_date: "2032-12-31T00:00:00Z"
                  extra_fields:
                    curp: "ROMC850315HDFRRS07"
                    rfc: "ROMC850315ABC"
                  validations:
                    - validated_at: "2025-01-15T14:32:45Z"
                      validation_result: "valid_id"
                      source: "ine"
                  source:
                    item_id: 45678
                    document_url: "https://files.sandbox.gotrebol.com/example-verification-id/45678_original_file.pdf?response-content-type=application%2Fpdf&response-content-disposition=inline&Expires=1762987062&Key-Pair-Id=EXAMPLE&Signature=ExampleSignature"
                    item_type: "person_id"
                    document_date: "2030-06-30"
                    document_number: "ROMC850315HDFRRS07"
                    entity_name: "RODRIGUEZ MARTINEZ CARLOS ALBERTO"
                    extra_fields:
                      idType: "ine_mx"
                  mx_address:
                    direccion:
                      pais: "México"
                      localidad: ""
                      codigo_postal: "03100"
                      tipo_interior: ""
                      tipo_vialidad: "Avenida"
                      nombre_vialidad: "Insurgentes Sur"
                      numero_exterior: "1647"
                      numero_interior: ""
                      tipo_asentamiento: "Colonia"
                      entidad_federativa: "Ciudad de México"
                      nombre_asentamiento: "Del Valle"
                      municipio_o_ente_territorial: "BENITO JUAREZ"
                    explicacion:
                      - "La dirección proporcionada se descompone en varios componentes según la tabla de estructura de direcciones en México."
                      - "El tipo de vialidad es 'Avenida', identificado por el término 'AV'."
                      - "El nombre de la vialidad es 'Insurgentes Sur'."
                      - "El número exterior es '1647'."
                      - "El tipo de asentamiento es 'Colonia', identificado por el término 'COL'."
                      - "El nombre del asentamiento es 'Del Valle'."
                      - "El municipio es 'BENITO JUAREZ'."
                      - "La entidad federativa es 'Ciudad de México'."
                      - "El código postal es '03100'."
              basic_data:
                first_name: "CARLOS ALBERTO"
                other_names: ""
                first_last_name: "RODRIGUEZ"
                other_last_names: "MARTINEZ"
              fiscal: {}
              address: {}
              external_identities:
                curp:
                  search_number: "ROMC850315HDFRRS07"
                  success: true
                  message: null
                  applicant_data:
                    curp: "ROMC850315HDFRRS07"
                    names: "CARLOS ALBERTO"
                    gender: "HOMBRE"
                    birth_date: "1985-03-15"
                    birth_entity: "DISTRITO FEDERAL"
                    nationality: "MEXICO"
                    first_surname: "RODRIGUEZ"
                    second_surname: "MARTINEZ"
                    evidentiary_document: "Acta de nacimiento"
                  evidentiary_document_data:
                    act_number: "00452"
                    registry_date: "1985"
                    register_entity: "09 DISTRITO FEDERAL"
                    register_municipality: "014 BENITO JUAREZ"
                  curp_file: "https://files.sandbox.gotrebol.com/mx/curps/ROMC850315HDFRRS07_file.pdf?response-content-type=application%2Fpdf&response-content-disposition=inline&Expires=1762987062&Key-Pair-Id=EXAMPLE&Signature=ExampleSignature"
              people_id: 5234
              ai_suggested: false
              human_reviewed: true
          signatory_groups: {}
          full_list:
            - names: "RODRIGUEZ MARTINEZ CARLOS ALBERTO"
              id_number: "ROMC850315HDFRRS07"
              id_type: "curp"
              type: "person"
              gender: "HOMBRE"
              nationality: "MEXICO"
              iso_country_code: "MX"
              birth_date: "1985-03-15"
              birth_entity: "DISTRITO FEDERAL"
              identity:
                person_id:
                  description: "ine_mx - ROMC850315HDFRRS07"
                  address: "AV INSURGENTES SUR 1647 COL DEL VALLE BENITO JUAREZ, CDMX"
                  document_date: "2030-06-30"
                  extra_fields:
                    curp: "ROMC850315HDFRRS07"
                    rfc: "ROMC850315ABC"
                  validations:
                    - validated_at: "2025-01-15T14:32:45Z"
                      validation_result: "valid_id"
                      source: "ine"
                  source:
                    item_id: 45678
                    document_url: "https://files.sandbox.gotrebol.com/example-verification-id/45678_original_file.pdf?response-content-type=application%2Fpdf&response-content-disposition=inline&Expires=1762987062&Key-Pair-Id=EXAMPLE&Signature=ExampleSignature"
                    item_type: "person_id"
                    document_date: "2030-06-30"
                    document_number: "ROMC850315HDFRRS07"
                    entity_name: "RODRIGUEZ MARTINEZ CARLOS ALBERTO"
                    extra_fields:
                      idType: "ine_mx"
                  mx_address:
                    direccion:
                      pais: "México"
                      localidad: ""
                      codigo_postal: "03100"
                      tipo_interior: ""
                      tipo_vialidad: "Avenida"
                      nombre_vialidad: "Insurgentes Sur"
                      numero_exterior: "1647"
                      numero_interior: ""
                      tipo_asentamiento: "Colonia"
                      entidad_federativa: "Ciudad de México"
                      nombre_asentamiento: "Del Valle"
                      municipio_o_ente_territorial: "BENITO JUAREZ"
                    explicacion:
                      - "La dirección proporcionada se descompone en varios componentes según la tabla de estructura de direcciones en México."
                      - "El tipo de vialidad es 'Avenida', identificado por el término 'AV'."
                      - "El nombre de la vialidad es 'Insurgentes Sur'."
                      - "El número exterior es '1647'."
                      - "El tipo de asentamiento es 'Colonia', identificado por el término 'COL'."
                      - "El nombre del asentamiento es 'Del Valle'."
                      - "El municipio es 'BENITO JUAREZ'."
                      - "La entidad federativa es 'Ciudad de México'."
                      - "El código postal es '03100'."
              basic_data:
                first_name: "CARLOS ALBERTO"
                other_names: ""
                first_last_name: "RODRIGUEZ"
                other_last_names: "MARTINEZ"
              fiscal: {}
              address: {}
              external_identities:
                curp:
                  search_number: "ROMC850315HDFRRS07"
                  success: true
                  message: null
                  applicant_data:
                    curp: "ROMC850315HDFRRS07"
                    names: "CARLOS ALBERTO"
                    gender: "HOMBRE"
                    birth_date: "1985-03-15"
                    birth_entity: "DISTRITO FEDERAL"
                    nationality: "MEXICO"
                    first_surname: "RODRIGUEZ"
                    second_surname: "MARTINEZ"
                    evidentiary_document: "Acta de nacimiento"
                  evidentiary_document_data:
                    act_number: "00452"
                    registry_date: "1985"
                    register_entity: "09 DISTRITO FEDERAL"
                    register_municipality: "014 BENITO JUAREZ"
                  curp_file: "https://files.sandbox.gotrebol.com/mx/curps/ROMC850315HDFRRS07_file.pdf?response-content-type=application%2Fpdf&response-content-disposition=inline&Expires=1762987062&Key-Pair-Id=EXAMPLE&Signature=ExampleSignature"
              people_id: 5234
              ai_suggested: false
              human_reviewed: true
        meta:
          section: "people"
          verification:
            id: "c8dc41fc-c477-404e-aff7-b9074f86d6d1"
            tag: "mi-etiqueta"
            status: "pending"
    V2DocumentsExample:
      summary: documents
      value:
        success: true
        data:
          documents:
            - url: "https://files.gotrebol.com/.../original.pdf"
              created_at: "2024-11-01T10:00:00.000Z"
              item_type: "csf_mx"
              hash: "a3f2..."
        meta:
          section: "documents"
          verification:
            id: "c8dc41fc-c477-404e-aff7-b9074f86d6d1"
            tag: "mi-etiqueta"
            status: "pending"
    V2CorporateHistoryExample:
      summary: corporate-history
      value:
        success: true
        data:
          schema_version: "1.0"
          verification_id: "018f2c7a-4b91-7d3e-a6f1-2c8d5e9b0a44"
          generated_at: "2026-08-27T15:04:00.000Z"
          coverage:
            siger:
              folios_queried: ["N-2022032489"]
              queried_at: "2026-04-14T19:47:03.000Z"
              entries_returned: 4
              folios_returned: 1
            background:
              extracted_from: ["6869", "103930", "4262"]
              records_unidentified: 0
              unreadable_extractions: []
              numbers_corrected:
                - cited_in: "6869"
                  literal: "mil trescientos veintidós"
                  reported: "1326"
                  corrected: "1322"
            combined:
              earliest_timeline_date: "1982-06-10"
              latest_timeline_date: "2024-05-13"
              no_acta_after: "2024-02-29"
          contribution:
            total_actas: 5
            in_siger: 2
            in_background: 3
            in_client_file: 2
            only_in_siger: 1
            only_in_background: 2
            only_in_client_file: 1
          history:
            - acta_number: "4262"
              folios: ["N-2022032489"]
              item_id: 1626845
              alias_numbers: []
              acta_type: "aa_mx"
              assembly_type: "General"
              formalized_by:
                type: "notario"
                name: "VILLALOBOS"
                number: "119"
                city: "México"
              assembly_date: "2014-12-15"
              instrument_date: "2019-10-16"
              registration_date: "2022-05-09"
              timeline_date: "2019-10-16"
              sources: ["siger", "background", "client_file"]
              proof_document:
                item_id: 1626845
                origin: "client_upload"
                url: "https://files.example/1626845.pdf"
              registry_entries:
                - folio: "N-2022032489"
                  row: 2
                  page: 1
                  nci: "202200110421"
                  label: "Cambio de domicilio social"
                  form: "M2 - Asamblea"
                  mode: "Inscripción vía web inmediata"
                  admitted_at: "2022-05-09"
                  registered_at: "2022-05-09"
                  modifications:
                    - type: "Acuerdo de disolución de la sociedad."
                      value: true
                  proof_document_url: "https://files.example/4262_1_2_file.pdf"
                - folio: "N-2022032489"
                  row: 3
                  page: 1
                  nci: "202200110422"
                  label: "Otros acuerdos que conforme a la Ley deban de registrarse"
                  form: "M2 - Asamblea"
                  mode: "Inscripción vía web inmediata"
                  admitted_at: "2022-05-09"
                  registered_at: "2022-05-09"
                  modifications: []
                  proof_document_url: null
              cites: ["18694"]
              cited_by: ["103930"]
              changes:
                - event_type: "constitucion_modificacion_domicilio"
                  description: "Cambio de domicilio social."
                  sources: ["siger"]
                  reported_by:
                    registry_entries:
                      - folio: "N-2022032489"
                        row: 2
                    citing_actas: []
                - event_type: "aumento_capital"
                  description: "Se aprueba un aumento de capital social por 700,000.00."
                  sources: ["background"]
                  reported_by:
                    registry_entries: []
                    citing_actas: ["103930"]
              evidence:
                - cited_in: "103930"
                  cited_in_date: "2023-12-14"
                  page: "4"
                  quote: "POR ESCRITURA PÚBLICA NÚMERO CUATRO MIL DOSCIENTOS SESENTA Y DOS..."
            - acta_number: "18694"
              folios: []
              item_id: null
              alias_numbers: []
              acta_type: null
              assembly_type: "protocolización"
              formalized_by:
                type: "notario"
                name: "Emmanuel Villicaña Estrada"
                number: "35"
                city: "Tlalnepantla, Estado de México"
              assembly_date: "1996-12-13"
              instrument_date: null
              registration_date: null
              timeline_date: "1996-12-13"
              sources: ["background"]
              proof_document: null
              registry_entries: []
              cites: []
              cited_by: ["103930", "4262"]
              changes:
                - event_type: "fusion"
                  description: "Protocolización del convenio de fusión de INDESIN como sociedad fusionante con INTERPROS."
                  sources: ["background"]
                  reported_by:
                    registry_entries: []
                    citing_actas: ["103930", "4262"]
              evidence:
                - cited_in: "103930"
                  cited_in_date: "2023-12-14"
                  page: "3"
                  quote: "POR ESCRITURA PÚBLICA NÚMERO DIECIOCHO MIL SEISCIENTOS NOVENTA Y CUATRO... DE FECHA TRECE DE DICIEMBRE DE MIL NOVECIENTOS NOVENTA Y SEIS..."
                - cited_in: "4262"
                  cited_in_date: "2014-12-15"
                  page: "3"
                  quote: "V.- ACTA DE ASAMBLEA.- POR ESCRITURA PÚBLICA NÚMERO DIECIOCHO MIL SEISCIENTOS NOVENTA Y CUATRO... DE FECHA TRECE DE SEPTIEMBRE DEL AÑO DE MIL NOVECIENTOS NOVENTA Y SIETE..."
          document_check:
            summary:
              actas_in_history: 5
              client_uploaded: 2
              not_uploaded_by_client: 3
        meta:
          section: "corporate-history"
          verification:
            id: "018f2c7a-4b91-7d3e-a6f1-2c8d5e9b0a44"
            tag: "indesin"
            status: "finished"

    V2SourcesExample:
      summary: sources
      value:
        success: true
        data:
          sources:
            - id: 25440
              type: "ac_mx"
              entity_name: "TREBOL OPCO S.A. DE C.V."
              document_number: "ACT-123"
              document_date: "2024-10-12"
              original_file_url: "https://files.gotrebol.com/.../original.pdf"
              user_event_completed_at: "2024-11-01T10:00:00.000Z"
              user_event_name: "upload_document"
              invalidated: false
              classified_at: "2024-11-01T10:00:00.000Z"
              item_status: "complete"
              notary_name: "Lic. Pérez"
              notary_number: "112"
              folio_number: "FN-123"
              folio_date: "2024-10-12"
              folio_inscription_date: "2024-10-20"
              notary_state: "CDMX"
              notary_city: "CDMX"
              cp_mi_procesamiento_acta:
                campo_ejemplo: "valor extraído"
        meta:
          section: "sources"
          verification:
            id: "c8dc41fc-c477-404e-aff7-b9074f86d6d1"
            tag: "mi-etiqueta"
            status: "pending"
    V2ExternalLookupsExample:
      summary: external-lookups
      value:
        success: true
        data:
          - source: "sat"
            lookup_type: "signature_certificates"
            agency_name: "Servicio de Administración Tributaria (SAT)"
            subject_type: "business"
            subject_name: "EMPRESA EJEMPLO SA DE CV"
            subject_identifier: "ABC123456789"
            queried_at: "2026-06-16T18:25:00.000Z"
            status: "success"
            evidence:
              - type: "screenshot"
                url: "https://files.gotrebol.com/.../sat-screenshot.jpg?...firma..."
                label: "SAT certificate lookup screenshot"
                generated_at: "2026-06-16T18:25:00.000Z"
                expires_at: "2026-06-16T19:25:00.000Z"
            data:
              tax_id: "ABC123456789"
              legal_name: "EMPRESA EJEMPLO SA DE CV"
              business_type: "SOCIEDAD ANONIMA DE CAPITAL VARIABLE"
              certificates:
                - serial_number: "00001000000700333012"
                  status: "Activo"
                  type: "SELLO"
                  start_date: "2023-01-01T00:00:00.000Z"
                  end_date: "2027-12-31T23:59:59.000Z"
                  legal_representative_rfc: "REP123456EF1"
                  person_email: null
          - source: "sat"
            lookup_type: "csf_qr_validation"
            agency_name: "Servicio de Administración Tributaria (SAT)"
            subject_type: "business"
            subject_name: "EMPRESA EJEMPLO SA DE CV"
            subject_identifier: "ABC123456789"
            queried_at: "2026-06-16T18:22:00.000Z"
            status: "success"
            evidence:
              - type: "external_link"
                url: "https://siat.sat.gob.mx/app/qr/faces/pages/mobile/validadorqr.jsf?D1=10&D2=1&D3=..."
                label: "SAT CSF QR validator"
                generated_at: null
                expires_at: null
            data:
              validation_result: "VALID"
              validation_status: "completed"
              validation_message: "Constancia válida y vigente."
              constancia_type: "moral"
          - source: "renapo"
            lookup_type: "curp"
            agency_name: "Registro Nacional de Población (RENAPO)"
            subject_type: "person"
            subject_name: "Juan Carlos Pérez García"
            subject_identifier: "PERE800101HDFXXX01"
            queried_at: null
            status: "success"
            evidence:
              - type: "pdf"
                url: "https://files.gotrebol.com/.../renapo-curp.pdf?...firma..."
                label: "RENAPO CURP certificate"
                generated_at: null
                expires_at: "2026-06-16T19:25:00.000Z"
            data:
              curp: "PERE800101HDFXXX01"
              curp_status: "alta_normal"
              names: "Juan Carlos"
              first_surname: "Pérez"
              second_surname: "García"
          - source: "ine"
            lookup_type: "lista_nominal"
            agency_name: "Instituto Nacional Electoral (INE)"
            subject_type: "person"
            subject_name: "Juan Carlos Pérez García"
            subject_identifier: "PEREJC80010112H300"
            queried_at: "2026-06-16T18:20:00.000Z"
            status: "success"
            evidence: []
            data:
              validation_message: "Credencial válida y vigente en lista nominal."
          - source: "siger"
            lookup_type: "commercial_registry"
            agency_name: "Sistema Integral de Gestión Registral (SIGER)"
            subject_type: "business"
            subject_name: "EMPRESA EJEMPLO SA DE CV"
            subject_identifier: "N-2024038395"
            queried_at: "2026-06-16T18:15:00.000Z"
            status: "success"
            evidence: []
            data:
              legal_name: "EMPRESA EJEMPLO SA DE CV"
              fme_number: "N-2024038395"
              fme_status: "Activo"
              federal_entity: "Ciudad de México"
        meta:
          section: "external-lookups"
          verification:
            id: "c8dc41fc-c477-404e-aff7-b9074f86d6d1"
            tag: "mi-etiqueta"
            status: "finished"
  schemas:
    V2VerificationMeta:
      type: object
      properties:
        id: { type: string }
        tag: { type: string, nullable: true }
        status: { type: string, nullable: true }

    V2Meta:
      type: object
      properties:
        section:
          type: string
          enum:
            [
              details,
              shareholders,
              people,
              documents,
              sources,
              external-lookups,
            ]
        verification:
          $ref: "#/components/schemas/V2VerificationMeta"

    V2PublicValidation:
      type: object
      properties:
        cross_check_value: { type: string }
        cross_check:
          { type: string, enum: [match, no_match, no_csf, no_qr, not_found] }
        item_type: { type: string }
        custom_message: { type: string, nullable: true }

    V2PublicSource:
      type: object
      properties:
        item_id: { type: number }
        subject_id: { type: number, nullable: true }
        item_type: { type: string }
        document_url: { type: string, format: uri, nullable: true }
        document_date: { type: string, nullable: true }
        document_number: { type: string, nullable: true }
        entity_name: { type: string, nullable: true }
        extra_fields:
          type: object
          additionalProperties: true
          nullable: true
        information_source: { type: string, nullable: true }
        source_date: { type: string, nullable: true }

    V2PublicFieldValue:
      type: object
      properties:
        value:
          oneOf:
            - type: string
            - type: boolean
        source: { $ref: "#/components/schemas/V2PublicSource" }
        note: { type: string, nullable: true }
        validations:
          type: array
          items: { $ref: "#/components/schemas/V2PublicValidation" }
          nullable: true
      nullable: true

    V2PublicJSONValue:
      type: object
      properties:
        value:
          type: object
          additionalProperties: true
        source: { $ref: "#/components/schemas/V2PublicSource" }
        validations:
          type: array
          items: { $ref: "#/components/schemas/V2PublicValidation" }
          nullable: true
      nullable: true

    V2PublicCsfBusinessActivity:
      type: object
      properties:
        order: { type: number }
        economic_activity: { type: string }
        percentage: { type: number }
        date: { type: string }

    V2DetailsData:
      type: object
      properties:
        verification:
          type: object
          properties:
            id: { type: string }
            account_id: { type: string }
            tag: { type: string, nullable: true }
            created_at: { type: string }
            comments_legal_review:
              type: array
              items: { type: string }
              nullable: true
            business_name:
              type: object
              properties:
                value: { type: string }
                validations:
                  type: array
                  items: { $ref: "#/components/schemas/V2PublicValidation" }
            flow_id: { type: string, nullable: true }
            onboarding_url: { type: string }
            documents_status: { type: string, nullable: true }
            created_by: { type: string }
            status: { type: string, nullable: true }
            country: { type: string }
            tax_id: { type: string, nullable: true }
        legal:
          type: object
          properties:
            business_name: { $ref: "#/components/schemas/V2PublicFieldValue" }
            business_type: { $ref: "#/components/schemas/V2PublicFieldValue" }
            business_folio_number:
              { $ref: "#/components/schemas/V2PublicFieldValue" }
            business_duration:
              { $ref: "#/components/schemas/V2PublicFieldValue" }
            business_expiry_date:
              { $ref: "#/components/schemas/V2PublicFieldValue" }
            business_legal_address:
              { $ref: "#/components/schemas/V2PublicFieldValue" }
            business_creditor_ability:
              { $ref: "#/components/schemas/V2PublicFieldValue" }
            business_asset_pledging:
              { $ref: "#/components/schemas/V2PublicFieldValue" }
            business_guarantor_ability:
              { $ref: "#/components/schemas/V2PublicFieldValue" }
            latest_acta_date:
              { $ref: "#/components/schemas/V2PublicFieldValue" }
            corporate_purpose:
              type: object
              properties:
                value:
                  {
                    type: object,
                    properties:
                      {
                        full_text: { type: string },
                        summary: { type: string },
                      },
                  }
                source: { $ref: "#/components/schemas/V2PublicSource" }
        registration:
          type: object
          properties:
            has_constitutive:
              { $ref: "#/components/schemas/V2PublicFieldValue" }
            business_name: { $ref: "#/components/schemas/V2PublicFieldValue" }
            acta_number: { $ref: "#/components/schemas/V2PublicFieldValue" }
            notary_number: { $ref: "#/components/schemas/V2PublicFieldValue" }
            notary_name: { $ref: "#/components/schemas/V2PublicFieldValue" }
            business_type: { $ref: "#/components/schemas/V2PublicFieldValue" }
            folio_number: { $ref: "#/components/schemas/V2PublicFieldValue" }
            folio_date: { $ref: "#/components/schemas/V2PublicFieldValue" }
            folio_inscription_date:
              { $ref: "#/components/schemas/V2PublicFieldValue" }
            city: { $ref: "#/components/schemas/V2PublicFieldValue" }
            state: { $ref: "#/components/schemas/V2PublicFieldValue" }
            registration_date:
              { $ref: "#/components/schemas/V2PublicFieldValue" }
        tax:
          type: object
          properties:
            has_constancia: { $ref: "#/components/schemas/V2PublicFieldValue" }
            business_name: { $ref: "#/components/schemas/V2PublicFieldValue" }
            business_type: { $ref: "#/components/schemas/V2PublicFieldValue" }
            business_tax_id: { $ref: "#/components/schemas/V2PublicFieldValue" }
            business_main_activity:
              type: object
              properties:
                value:
                  type: array
                  items:
                    $ref: "#/components/schemas/V2PublicCsfBusinessActivity"
                source:
                  $ref: "#/components/schemas/V2PublicSource"
                validations:
                  type: array
                  items:
                    $ref: "#/components/schemas/V2PublicValidation"
                  nullable: true
              nullable: true
            business_fiscal_status:
              { $ref: "#/components/schemas/V2PublicFieldValue" }
            qr_validation: { $ref: "#/components/schemas/V2PublicFieldValue" }
            business_regime: { $ref: "#/components/schemas/V2PublicFieldValue" }
            additional_data: { $ref: "#/components/schemas/V2PublicJSONValue" }
        signatory_validation:
          type: object
          properties:
            full_name: { $ref: "#/components/schemas/V2PublicFieldValue" }
            paternal_last_name:
              { $ref: "#/components/schemas/V2PublicFieldValue" }
            maternal_last_name:
              { $ref: "#/components/schemas/V2PublicFieldValue" }
            document_number: { $ref: "#/components/schemas/V2PublicFieldValue" }
            validation_status:
              { $ref: "#/components/schemas/V2PublicFieldValue" }
            validation_value:
              { $ref: "#/components/schemas/V2PublicFieldValue" }
            validation_date: { $ref: "#/components/schemas/V2PublicFieldValue" }
            name_comparison_result:
              { $ref: "#/components/schemas/V2PublicFieldValue" }
            id_validation_provider:
              { $ref: "#/components/schemas/V2PublicJSONValue" }
        banking:
          type: object
          properties:
            address: { $ref: "#/components/schemas/V2PublicFieldValue" }
            entity_name: { $ref: "#/components/schemas/V2PublicFieldValue" }
            document_date: { $ref: "#/components/schemas/V2PublicFieldValue" }
            document_number: { $ref: "#/components/schemas/V2PublicFieldValue" }
            additional_data: { $ref: "#/components/schemas/V2PublicJSONValue" }
        address:
          type: object
          properties:
            business_fiscal_address:
              { $ref: "#/components/schemas/V2PublicFieldValue" }
            business_fiscal_address_disaggregated:
              { $ref: "#/components/schemas/V2PublicJSONValue" }
            business_comercial_address:
              { $ref: "#/components/schemas/V2PublicFieldValue" }

    V2RoleGroupName:
      type: string
      description: Categoría estandarizada del rol.
      enum: ["board_members", "executives", "proxies", "auditors"]

    V2RoleEventName:
      type: string
      description: Evento normalizado que originó el rol. Un rol `mentioned` indica que el acta menciona a la persona con ese rol. En `key_people`, solo se incluye si al menos un elemento de `powers` tiene `has_power` en `true`. En `signatory_groups` se incluye siempre.
      enum: ["addition", "mentioned", "renewal", "removal"]

    V2KeyPersonRole:
      type: object
      properties:
        id: { type: string, nullable: true }
        role_name: { type: string }
        group_name: { $ref: "#/components/schemas/V2RoleGroupName" }
        event: { $ref: "#/components/schemas/V2RoleEventName" }
        duration: { type: number }
        powers:
          type: array
          items: { type: object, additionalProperties: true }
        source: { $ref: "#/components/schemas/V2PublicSource" }
        powers_due_date: { type: string, nullable: true }
        powers_due_date_source:
          { type: string, enum: ["legal", "document"], nullable: true }

    V2KeyPerson:
      type: object
      properties:
        names: { type: string }
        id_number: { type: string, nullable: true }
        id_number_rfc: { type: string, nullable: true }
        id_type:
          type: string
          nullable: true
          description: Tipo de identificación utilizado. Los valores posibles son "rfc" o "curp", si hubo coincidencia, de lo contrario null.
          enum: ["rfc", "curp", null]
        type:
          type: string
          nullable: true
          description: Tipo de entidad. Los valores posibles son "person" o "business".
          enum: ["person", "business"]
        gender: { type: string, nullable: true }
        nationality:
          type: string
          nullable: true
          description: |
            Nacionalidad de la persona. Este campo tomará el valor de los datos CURP cuando existan (disponible en `external_identities.curp.applicant_data.nationality`).
        iso_country_code:
          type: string
          nullable: true
          description: |
            Código de país ISO 3166-1 alpha-2 (dos letras) derivado de la nacionalidad. Ejemplos: "MX" para México, "US" para Estados Unidos, "PE" para Perú. Este campo convierte el texto de nacionalidad a su código ISO estándar.
        birth_date: { type: string, nullable: true }
        birth_entity: { type: string, nullable: true }
        roles:
          type: array
          items: { $ref: "#/components/schemas/V2KeyPersonRole" }
        identity: { $ref: "#/components/schemas/IdentityMatch" }
        fiscal: { $ref: "#/components/schemas/FiscalMatch" }
        address: { $ref: "#/components/schemas/AddressMatch" }
        ubo_forms: { type: object, additionalProperties: true, nullable: true }
        external_identities:
          {
            $ref: "#/components/schemas/PublicExternalIdentities",
            nullable: true,
          }
        people_id: { type: number }
        ai_suggested: { type: boolean, nullable: true }
        human_reviewed: { type: boolean, nullable: true }

    V2SignatoryGroupItem:
      type: object
      properties:
        role_id: { type: string, nullable: true }
        names: { type: string }
        id_number: { type: string }
        id_number_rfc: { type: string, nullable: true }
        id_type: { type: string }
        role_name: { type: string }
        event: { $ref: "#/components/schemas/V2RoleEventName" }
        duration: { type: number }
        source: { $ref: "#/components/schemas/V2PublicSource" }
        type: { type: string, nullable: true }
        fiscal: { $ref: "#/components/schemas/FiscalMatch" }
        identity: { $ref: "#/components/schemas/IdentityMatch" }
        address: { $ref: "#/components/schemas/AddressMatch" }
        external_identities:
          {
            $ref: "#/components/schemas/PublicExternalIdentities",
            nullable: true,
          }
        ubo_forms: { type: object, additionalProperties: true, nullable: true }
        folio_number: { type: string, nullable: true }
        folio_date: { type: string, nullable: true }
        folio_inscription_date: { type: string, nullable: true }
        iso_country_code:
          type: string
          nullable: true
          description: |
            Código de país ISO 3166-1 alpha-2 (dos letras) derivado de la nacionalidad. Ejemplos: "MX" para México, "US" para Estados Unidos, "PE" para Perú. Este campo convierte el texto de nacionalidad a su código ISO estándar.

    V2FullPeopleItem:
      type: object
      properties:
        names: { type: string }
        id_number: { type: string, nullable: true }
        id_number_rfc: { type: string, nullable: true }
        id_type:
          type: string
          nullable: true
          description: Tipo de identificación utilizado. Los valores posibles son "rfc" o "curp" si hubo coincidencia, de lo contrario null.
          enum: ["rfc", "curp", null]
        type:
          type: string
          nullable: true
          description: Tipo de entidad. Los valores posibles son "person" o "business".
          enum: ["person", "business"]
        gender: { type: string, nullable: true }
        nationality:
          type: string
          nullable: true
          description: |
            Nacionalidad de la persona. Este campo tomará el valor de los datos CURP cuando existan (disponible en `external_identities.curp.applicant_data.nationality`).
        iso_country_code:
          type: string
          nullable: true
          description: |
            Código de país ISO 3166-1 alpha-2 (dos letras) derivado de la nacionalidad. Ejemplos: "MX" para México, "US" para Estados Unidos, "PE" para Perú. Este campo convierte el texto de nacionalidad a su código ISO estándar.
        birth_date: { type: string, nullable: true }
        birth_entity: { type: string, nullable: true }
        identity: { $ref: "#/components/schemas/IdentityMatch" }
        fiscal: { $ref: "#/components/schemas/FiscalMatch" }
        address: { $ref: "#/components/schemas/AddressMatch" }
        ubo_forms: { type: object, additionalProperties: true, nullable: true }
        external_identities:
          {
            $ref: "#/components/schemas/PublicExternalIdentities",
            nullable: true,
          }
        people_id: { type: number }
        ai_suggested: { type: boolean, nullable: true }
        human_reviewed: { type: boolean, nullable: true }

    PublicCurpApplicantData:
      type: object
      properties:
        curp: { type: string }
        names: { type: string }
        gender: { type: string }
        birth_date: { type: string }
        birth_entity: { type: string }
        nationality: { type: string }
        first_surname: { type: string }
        second_surname: { type: string }
        evidentiary_document: { type: string }

    PublicCurpEvidentiaryDocumentData:
      type: object
      properties:
        act_number: { type: string }
        registry_date: { type: string }
        register_entity: { type: string }
        register_municipality: { type: string }

    PublicCurpExternalIdentity:
      type: object
      properties:
        search_number:
          type: string
          nullable: true
          description: >
            Número de búsqueda utilizado para la consulta CURP. Puede diferir
            del CURP retornado en los datos del solicitante.
        success: { type: boolean }
        message: { type: string, nullable: true }
        applicant_data:
          {
            $ref: "#/components/schemas/PublicCurpApplicantData",
            nullable: true,
          }
        evidentiary_document_data:
          {
            $ref: "#/components/schemas/PublicCurpEvidentiaryDocumentData",
            nullable: true,
          }
        curp_file:
          type: string
          nullable: true
          description: >
            URL firmada al PDF descargado de RENAPO con la constancia del
            CURP. La URL incluye un parámetro `Expires=…` y caduca; cuando
            expire, vuelve a consultar el endpoint para obtener una URL
            renovada.

    PublicExternalIdentities:
      type: object
      properties:
        curp:
          {
            $ref: "#/components/schemas/PublicCurpExternalIdentity",
            nullable: true,
          }

    V2PeopleData:
      type: object
      properties:
        key_people:
          type: array
          items: { $ref: "#/components/schemas/V2KeyPerson" }
        signatory_groups:
          type: object
          description: |
            Mapa de grupos de roles. Las llaves corresponden a `V2RoleGroupName`:
            "board_members", "executives", "proxies", "auditors".
          additionalProperties:
            type: array
            items: { $ref: "#/components/schemas/V2SignatoryGroupItem" }
        full_list:
          type: array
          items: { $ref: "#/components/schemas/V2FullPeopleItem" }
        citations:
          type: object
          description: |
            Presente solo cuando se llamó con `?with_citations=true`. Contiene la URL firmada (CloudFront) al artifact de coordenadas en S3, que mapea cada field extraído a sus `bounding_boxes` dentro del PDF original. Ver [Coordenadas de citas](/guia-devs/referencia/coordenadas-citas).
          properties:
            url:
              type: string
              format: uri
              description: |
                URL firmada y temporal. Descarga el JSON cuanto antes; si caduca, vuelve a llamar al endpoint con el flag para obtener una nueva. Si el artifact aún no se horneó para esta verificación, no se devuelve la llave citations.
              example: "https://files.gotrebol.com/{verification_id}/citations/people.json?Expires=…&Signature=…"
          required:
            - url

    V2Shareholder:
      type: object
      properties:
        id: { type: number }
        currency: { type: string }
        fixed_shares: { type: string }
        fixed_value: { type: string }
        id_number: { type: string }
        id_number_rfc: { type: string, nullable: true }
        id_type: { type: string }
        name: { type: string }
        nationality: { type: string }
        iso_country_code:
          type: string
          nullable: true
          description: |
            Código de país ISO 3166-1 alpha-2 (dos letras) derivado de la nacionalidad. Ejemplos: "MX" para México, "US" para Estados Unidos, "PE" para Perú. Este campo convierte el texto de nacionalidad a su código ISO estándar.
        total_shares: { type: string }
        total_value: { type: string }
        type: { type: string }
        variable_shares: { type: string }
        variable_value: { type: string }
        share_percentage: { type: number }
        aml_validated_at: { type: string, nullable: true }
        aml_validation_status: { type: string, nullable: true }
        aml_risk_category:
          type: array
          items: { type: string }
        aml_data: { type: array, items: { type: object }, nullable: true }
        identity: { $ref: "#/components/schemas/IdentityMatch" }
        fiscal: { $ref: "#/components/schemas/FiscalMatch" }
        address: { $ref: "#/components/schemas/AddressMatch" }
        ubo_forms: { type: object, additionalProperties: true, nullable: true }
        external_identities:
          {
            $ref: "#/components/schemas/PublicExternalIdentities",
            nullable: true,
          }
        gender: { type: string, nullable: true }
        birth_date: { type: string, nullable: true }
        birth_entity: { type: string, nullable: true }

    V2CompanyCapital:
      type: object
      properties:
        fixed_value: { type: string }
        fixed_shares: { type: string }
        fixed_value_currency: { type: string }
        variable_value: { type: string }
        variable_shares: { type: string }
        variable_value_currency: { type: string }
        total_value: { type: string }
        total_shares: { type: string }
        total_value_currency: { type: string }

    V2ShareholdersData:
      type: object
      properties:
        shareholders:
          type: array
          items: { $ref: "#/components/schemas/V2Shareholder" }
        source:
          $ref: "#/components/schemas/V2PublicSource"
          nullable: true
        capital:
          $ref: "#/components/schemas/V2CompanyCapital"
          nullable: true
        shareholders_unavailable_reason:
          type: string
          nullable: true
          enum:
            ["business_type_without_shareholders", "pending_extraction", null]
          description: |
            Por qué `shareholders` viene vacío. `business_type_without_shareholders`: el tipo de sociedad no tiene accionistas y la lista vacía es la respuesta final. `pending_extraction`: hay un acta en extracción, así que la lista vacía todavía no dice nada. `null`: no hay motivo que reportar, sea porque hay accionistas o porque el tipo de sociedad sí los tiene. Solo lleva un motivo cuando la lista está vacía. Los dos campos siempre están presentes: lo opcional es el valor, no su presencia. Nunca se omiten del objeto, ni siquiera cuando hay accionistas — en ese caso `shareholders_unavailable_reason` llega en `null`. Campo aditivo, disponible desde el 20 de agosto de 2026. Ver [Motivo cuando la lista de accionistas viene vacía](/guia-devs/uso-kyb/mexico/accionistas#motivo-sin-accionistas).
          example: null
        business_type:
          type: string
          nullable: true
          description: |
            Tipo de sociedad del que Trébol derivó el motivo, tal como está escrito en el documento. Sale del acta más reciente y, si ninguna acta lo trae, de la constancia de situación fiscal. El campo siempre está presente; su valor es el tipo de sociedad cuando Trébol lo puede resolver y `null` cuando no, también cuando el motivo es `null`. No lo compares contra tu propia lista de tipos: usa `shareholders_unavailable_reason`. Campo aditivo, disponible desde el 20 de agosto de 2026.
          example: "SOCIEDAD ANONIMA DE CAPITAL VARIABLE"
        citations:
          type: object
          description: |
            Presente solo cuando se llamó con `?with_citations=true`. Contiene la URL firmada (CloudFront) al artifact de coordenadas en S3, que mapea cada field extraído a sus `bounding_boxes` dentro del PDF original. Ver [Coordenadas de citas](/guia-devs/referencia/coordenadas-citas).
          properties:
            url:
              type: string
              format: uri
              description: |
                URL firmada y temporal. Descarga el JSON cuanto antes; si caduca, vuelve a llamar al endpoint con el flag para obtener una nueva. Si el artifact aún no se horneó para esta verificación, no se devuelve la llave citations.
              example: "https://files.gotrebol.com/{verification_id}/citations/shareholders.json?Expires=…&Signature=…"
          required:
            - url

    V2VerificationDocument:
      type: object
      properties:
        url: { type: string, format: uri, nullable: true }
        created_at: { type: string, nullable: true }
        item_type: { type: string, nullable: true }
        hash: { type: string }

    V2DocumentsData:
      type: object
      properties:
        documents:
          type: array
          items: { $ref: "#/components/schemas/V2VerificationDocument" }

    V2CompanySource:
      type: object
      description: |
        Además de los campos listados, cada fuente puede incluir una llave por cada extracción personalizada con resultado para ese ítem, con la forma `cp_<prompt_id>`, donde `prompt_id` es el identificador editable de la extracción personalizada. El valor es un objeto JSON acorde al esquema de la versión que produjo el resultado. Ver [Extracciones personalizadas](/producto/guias/extracciones-personalizadas).

        Los tipos de ítem personalizados no usan este mecanismo. Un ítem `cit_*` aparece en `sources` con sus campos comunes, pero sin llaves `cp_` y sin `item_value`: sus resultados de extracción y validación se leen desde el ítem, en `item_value.pipeline`. Ver [Tipos de ítem personalizados](/producto/guias/tipos-de-item-personalizados#donde-salen-los-resultados).
      additionalProperties: true
      properties:
        id: { type: number }
        type: { type: string }
        entity_name: { type: string, nullable: true }
        acta_type: { type: string, nullable: true }
        document_number: { type: string, nullable: true }
        document_date: { type: string, nullable: true }
        document_metadata:
          { type: object, additionalProperties: true, nullable: true }
        original_file_url: { type: string, format: uri, nullable: true }
        user_event_completed_at: { type: string, nullable: true }
        user_event_name: { type: string, nullable: true }
        invalidated: { type: boolean }
        options: { type: object, additionalProperties: true, nullable: true }
        field_confidences:
          { type: object, additionalProperties: true, nullable: true }
        validation_result:
          { type: object, additionalProperties: true, nullable: true }
        classified_at: { type: string, nullable: true }
        fme_date: { type: string, nullable: true }
        fme_folio_number: { type: string, nullable: true }
        fme_folio_date: { type: string, nullable: true }
        fme_folio_inscription_date: { type: string, nullable: true }
        item_value: { type: object, additionalProperties: true, nullable: true }
        item_status: { type: string }
        siger_folio_number: { type: string, nullable: true }
        siger_folio_date: { type: string, nullable: true }
        siger_folio_inscription_date: { type: string, nullable: true }
        is_duplicate_item: { type: boolean, nullable: true }
        notary_name: { type: string, nullable: true }
        notary_number: { type: string, nullable: true }
        folio_number: { type: string, nullable: true }
        folio_date: { type: string, nullable: true }
        folio_inscription_date: { type: string, nullable: true }
        notary_state: { type: string, nullable: true }
        notary_city: { type: string, nullable: true }
        assembly_minute:
          { type: object, additionalProperties: true, nullable: true }
        citations:
          type: object
          description: |
            Presente solo cuando se llamó con `?with_citations=true` y el ítem es de tipo acta. Contiene la URL firmada (CloudFront) al artifact de coordenadas en S3. Ver [Coordenadas de citas](/guia-devs/referencia/coordenadas-citas).
          properties:
            url:
              type: string
              format: uri
              description: |
                URL firmada y temporal. Descarga el JSON cuanto antes; si caduca, vuelve a llamar al endpoint con el flag para obtener una nueva. Si el artifact aún no se horneó para esta verificación, no se devuelve la llave citations.
              example: "https://files.gotrebol.com/{verification_id}/citations/sources/{item_id}.json?Expires=…&Signature=…"
          required:
            - url

    V2SourcesData:
      type: object
      properties:
        sources:
          type: array
          items: { $ref: "#/components/schemas/V2CompanySource" }

    V2PublicResponseCorporateHistory:
      type: object
      properties:
        success: { type: boolean, enum: [true] }
        data: { $ref: "#/components/schemas/CorporateHistory" }
        meta: { $ref: "#/components/schemas/CorporateHistoryMeta" }

    CorporateHistoryMeta:
      type: object
      properties:
        section: { type: string, enum: [corporate-history] }
        verification:
          $ref: "#/components/schemas/V2VerificationMeta"

    CorporateHistory:
      type: object
      properties:
        schema_version:
          type: string
          description: Versión del contrato. Los campos nuevos son aditivos.
          example: "1.0"
        verification_id: { type: string }
        generated_at:
          type: string
          format: date-time
          description: Momento en que se calculó esta respuesta.
        coverage: { $ref: "#/components/schemas/CorporateHistoryCoverage" }
        contribution:
          { $ref: "#/components/schemas/CorporateHistoryContribution" }
        history:
          type: array
          description: Una fila por acta, de la más reciente a la más antigua por `timeline_date`.
          items: { $ref: "#/components/schemas/CorporateHistoryActa" }
        document_check:
          type: object
          properties:
            summary:
              $ref: "#/components/schemas/CorporateHistoryDocumentCheck"

    CorporateHistoryActa:
      type: object
      properties:
        acta_number:
          type: string
          nullable: true
          description: |
            Número del instrumento, normalizado a dígitos para poder cruzarse entre fuentes. Es `null` cuando no hay nada con qué identificarla: un documento subido sin número, una inscripción cuyo número no trae dígitos, o cualquier fila del listado sin números de instrumento (ver `coverage.siger.no_instrument_numbers`). Un acta sin número no se fusiona con ninguna otra, porque no hay llave.
          example: "4262"
        folios:
          type: array
          items: { type: string }
          description: |
            FME de cada folio que inscribió el acta, empezando por el orden en que los devolvió el registro; vacío cuando ningún folio la tiene. Es una lista porque un mismo instrumento puede inscribirse más de una vez: los folios que devuelve una consulta son la misma empresa vista desde varias oficinas registrales, y una sociedad que cambió de domicilio queda inscrita en el folio que dejó y en el que llegó. La identidad de un acta es `acta_number` solo, así que esas inscripciones son un acta y esta es la lista de dónde quedó.
          example: ["N-2022032489"]
        item_id:
          type: integer
          nullable: true
          description: ID del item de verificación que contiene el documento, cuando existe.
        alias_numbers:
          type: array
          items: { type: string }
          description: Otros números con que alguna fuente se refirió al mismo instrumento.
        acta_type:
          type: string
          nullable: true
          description: Tipo de item con que se cargó el documento (`ac_mx`, `aa_mx`, `pw_mx`). Es `null` para un acta que solo conocen el folio o los antecedentes.
        assembly_type:
          type: string
          nullable: true
          description: Texto literal de la fuente ("General", "acta constitutiva", "protocolización"). Sin catálogo normalizado.
        formalized_by:
          type: object
          description: El fedatario, copiado de la fuente que lo traiga. No se concilia entre fuentes; el mismo corredor aparece escrito de tres formas distintas en tres actas.
          properties:
            type: { type: string, nullable: true }
            name: { type: string, nullable: true }
            number: { type: string, nullable: true }
            city: { type: string, nullable: true }
        assembly_date:
          type: string
          format: date
          nullable: true
          description: Cuándo se reunió la asamblea.
        instrument_date:
          type: string
          format: date
          nullable: true
          description: Cuándo un fedatario protocolizó el acta.
        registration_date:
          type: string
          format: date
          nullable: true
          description: Cuándo el registro la inscribió.
        timeline_date:
          type: string
          format: date
          nullable: true
          description: Llave de orden, con precedencia `instrument_date` → `registration_date` → `assembly_date`. El historial está ordenado por cuándo se documentó un cambio, no por cuándo ocurrió.
        sources:
          type: array
          description: Qué fuentes conocen esta acta, en orden canónico.
          items: { type: string, enum: [siger, background, client_file] }
        proof_document:
          type: object
          nullable: true
          description: |
            La copia del documento que tenemos. `origin` importa: `client_upload` es evidencia de que el cliente lo tiene; `siger_extraction` significa que nosotros lo bajamos del folio, así que el archivo es real pero **no** cuenta como cobertura del expediente.
          properties:
            item_id: { type: integer }
            origin: { type: string, enum: [client_upload, siger_extraction] }
            url: { type: string }
        registry_entries:
          type: array
          description: Las inscripciones que el folio hizo para este instrumento. Un acta con dos inscripciones es una fila con dos entradas, no dos filas.
          items: { $ref: "#/components/schemas/CorporateHistoryRegistryEntry" }
        cites:
          type: array
          items: { type: string }
          description: Números de acta que los antecedentes de **esta** acta refieren.
        cited_by:
          type: array
          items: { type: string }
          description: Actas cuyos antecedentes refieren a esta. Es lo que sostiene un acta que nadie subió.
        changes:
          type: array
          items: { $ref: "#/components/schemas/CorporateHistoryChange" }
        evidence:
          type: array
          description: Citas textuales que respaldan lo que se afirma de esta acta.
          items: { $ref: "#/components/schemas/CorporateHistoryEvidence" }

    CorporateHistoryRegistryEntry:
      type: object
      properties:
        folio:
          type: string
          nullable: true
          description: FME del folio que hizo la inscripción. Null cuando la fuente no lo nombró.
        row:
          type: integer
          description: |
            Renglón del acto dentro del folio. `folio` y `row` juntos son su identidad: los renglones se numeran por folio, así que en un acta inscrita en más de uno, `row` sólo identifica una entrada leído junto con `folio`. Por eso las referencias de `changes[].reported_by.registry_entries` traen las dos llaves.
        page: { type: integer, nullable: true }
        nci: { type: string, nullable: true }
        label:
          type: string
          description: El acto tal como el registro lo nombró.
        form:
          type: string
          nullable: true
          description: Forma precodificada, código y etiqueta juntos.
          example: "M2 - Asamblea"
        mode: { type: string, nullable: true }
        admitted_at:
          type: string
          format: date
          nullable: true
          description: Fecha de ingreso a ventanilla.
        registered_at:
          type: string
          format: date
          nullable: true
          description: Fecha de inscripción.
        modifications:
          type: array
          description: |
            Las casillas que el folio marcó en verdadero, copiadas literalmente y **sin interpretar**. `type` es la redacción que el registro imprimió, no un nombre de campo: las etiquetas varían entre formas del mismo folio. Sirven para ver que un acto marca disolución aunque ninguna fuente la describa.
          items:
            type: object
            properties:
              type: { type: string }
              value: { type: boolean }
        proof_document_url: { type: string, nullable: true }

    CorporateHistoryChange:
      type: object
      properties:
        event_type:
          type: string
          description: |
            Código del evento. El folio y los antecedentes usan **vocabularios disjuntos** (`modificacion_capital` vs `aumento_capital`) y no se fusionan: unirlos exigiría una tabla de equivalencias que deliberadamente no existe. Por eso ningún cambio trae las dos fuentes, y la corroboración cruzada se ve a nivel de acta, en `sources`.
          example: modificacion_capital
        description: { type: string }
        sources:
          type: array
          items: { type: string, enum: [siger, background, client_file] }
        reported_by:
          type: object
          description: |
            Quién reportó el cambio. Nunca las dos listas a la vez: `registry_entries` solo la llena el folio y `citing_actas` solo los antecedentes, porque sus vocabularios de `event_type` son disjuntos y un cambio no se fusiona entre fuentes.
          properties:
            registry_entries:
              type: array
              description: |
                Las inscripciones del folio que reportaron el cambio. Cada referencia resuelve contra `registry_entries` del acta por **las dos** llaves: los renglones se numeran por folio, así que en un acta inscrita en más de uno el `row` solo no identifica una entrada.
              items:
                type: object
                properties:
                  folio:
                    type: string
                    nullable: true
                    description: FME del folio que hizo la inscripción. Null cuando la fuente no lo nombró.
                  row:
                    type: integer
                    description: Renglón de la inscripción dentro de ese folio.
              example:
                [
                  { folio: "N-2022032489", row: 2 },
                  { folio: "N-2022032489", row: 3 },
                ]
            citing_actas:
              type: array
              items: { type: string }
              description: Números de las actas cuyos antecedentes mencionan el cambio.
              example: ["103930"]

    CorporateHistoryEvidence:
      type: object
      properties:
        cited_in:
          type: string
          description: Número del acta que contiene la cita.
        cited_in_date:
          type: string
          format: date
          nullable: true
          description: Fecha del acta que cita, para poder ordenar dos versiones de un mismo hecho.
        page: { type: string, nullable: true }
        quote:
          type: string
          description: Texto literal de la fuente.

    CorporateHistoryCoverage:
      type: object
      description: Hasta dónde vemos. Nunca afirma que el historial esté completo.
      properties:
        siger:
          type: object
          properties:
            folios_queried:
              type: array
              items: { type: string }
              description: FME de cada folio leído, en el orden en que SIGER los devolvió.
            queried_at: { type: string, format: date-time, nullable: true }
            entries_returned:
              type: integer
              description: Inscripciones que los folios devolvieron en total, antes de descartar ninguna.
            folios_returned: { type: integer }
            no_instrument_numbers:
              type: boolean
              description: |
                Presente y en verdadero cuando el listado del folio se encontró pero sus documentos nunca se descargaron. Esas filas no traen número de instrumento, así que no se pueden agrupar ni cruzar con nada — pero sí se emiten: que no podamos cruzar una inscripción no es razón para ocultar que el registro la hizo.
            filing_items_returned:
              type: integer
              description: Filas del listado, presente solo en el caso anterior.
        background:
          type: object
          properties:
            extracted_from:
              type: array
              items: { type: string }
              description: Números de las actas cuyos antecedentes se leyeron. Un acta del expediente que no aparezca aquí es un acta cuyos antecedentes no se extrajeron.
            records_unidentified:
              type: integer
              description: Registros que no nombraron un número de instrumento usable, así que describen un acta que no se puede ubicar. Se cuentan en vez de emitirse.
            unreadable_extractions:
              type: array
              items: { type: string }
              description: Actas cuya extracción existía pero no arrojó ningún registro legible. Se reporta porque una extracción que corrió y no produjo nada es un hueco en la cobertura, y un resultado vacío es indistinguible de un acta que genuinamente no cita nada.
            numbers_corrected:
              type: array
              description: |
                Números de instrumento que la extracción convirtió mal, corregidos a partir de la transcripción literal que ella misma escribió junto a ellos.

                Los antecedentes suelen escribir el número en letra ("mil trescientos veintidós") y la extracción lo devuelve en dígitos y transcrito. Los dígitos se verifican contra una lectura determinística de las palabras, y cuando difieren gana la lectura.

                Se reporta en vez de aplicarse en silencio porque la corrección cambia **qué acta es** esa fila: con qué inscripción del folio se cruza y qué documento se cuenta como faltante. Vacío para extracciones anteriores a que el prompt pidiera la transcripción, donde no hay contra qué verificar.
              items:
                type: object
                properties:
                  cited_in:
                    type: string
                    description: Acta cuyos antecedentes lo traían.
                  literal:
                    type: string
                    description: El número tal como el documento lo imprime.
                  reported:
                    type: string
                    description: Lo que la extracción escribió.
                  corrected:
                    type: string
                    description: Lo que el literal realmente dice, y lo que el historial usa.
        combined:
          type: object
          properties:
            earliest_timeline_date:
              { type: string, format: date, nullable: true }
            latest_timeline_date: { type: string, format: date, nullable: true }
            no_acta_after:
              type: string
              format: date
              nullable: true
              description: |
                Fecha de asamblea del acta más reciente del expediente. Es un hecho sobre nuestros datos, no sobre la empresa: los antecedentes de un acta solo alcanzan hasta su propia asamblea, así que un cambio posterior a esta fecha no sería visible ni aunque hubiera ocurrido.

    CorporateHistoryContribution:
      type: object
      description: Qué aportó cada fuente. `only_in_*` es lo que se habría perdido sin ella.
      properties:
        total_actas: { type: integer }
        in_siger: { type: integer }
        in_background: { type: integer }
        in_client_file: { type: integer }
        only_in_siger: { type: integer }
        only_in_background: { type: integer }
        only_in_client_file: { type: integer }

    CorporateHistoryDocumentCheck:
      type: object
      description: |
        Conteo objetivo del expediente, sin lista paralela y sin ranking. La lista de faltantes se deriva del historial: `history.filter(a => !a.sources.includes("client_file"))`. El criterio es la pertenencia a `sources`, no la presencia de `proof_document`: un acta que el cliente subió pero cuyo archivo no se pudo resolver sigue siendo un acta que tiene.
      properties:
        actas_in_history: { type: integer }
        client_uploaded: { type: integer }
        not_uploaded_by_client: { type: integer }

    V2PublicResponseDetails:
      type: object
      properties:
        success: { type: boolean, enum: [true] }
        data: { $ref: "#/components/schemas/V2DetailsData" }
        meta: { $ref: "#/components/schemas/V2Meta" }

    V2PublicResponsePeople:
      type: object
      properties:
        success: { type: boolean, enum: [true] }
        data: { $ref: "#/components/schemas/V2PeopleData" }
        meta: { $ref: "#/components/schemas/V2Meta" }

    V2PublicResponseShareholders:
      type: object
      properties:
        success: { type: boolean, enum: [true] }
        data: { $ref: "#/components/schemas/V2ShareholdersData" }
        meta: { $ref: "#/components/schemas/V2Meta" }

    V2PublicResponseDocuments:
      type: object
      properties:
        success: { type: boolean, enum: [true] }
        data: { $ref: "#/components/schemas/V2DocumentsData" }
        meta: { $ref: "#/components/schemas/V2Meta" }

    V2PublicResponseSources:
      type: object
      properties:
        success: { type: boolean, enum: [true] }
        data: { $ref: "#/components/schemas/V2SourcesData" }
        meta: { $ref: "#/components/schemas/V2Meta" }

    V2ExternalLookupEvidence:
      type: object
      description: Artefacto de soporte de una consulta externa.
      properties:
        type:
          type: string
          description: Tipo de evidencia.
          enum: [screenshot, pdf, external_link, trebol_report]
        url:
          type: string
          description: >
            URL del artefacto. Para `screenshot` y `pdf` es una URL firmada de corta
            duración (~1 hora); para `external_link` es la URL pública de la dependencia.
        label:
          {
            type: string,
            nullable: true,
            description: "Descripción legible del artefacto.",
          }
        generated_at:
          type: string
          nullable: true
          description: "Fecha (ISO 8601) en que se produjo el artefacto, si se conoce."
        expires_at:
          type: string
          nullable: true
          description: "Fecha (ISO 8601) en que expira la URL firmada. null para enlaces externos o estáticos."

    V2ExternalLookup:
      type: object
      description: Registro de una consulta realizada a una fuente pública o gubernamental.
      properties:
        source:
          type: string
          description: Fuente consultada.
          enum: [sat, renapo, ine, siger]
        lookup_type:
          type: string
          description: Tipo de consulta realizada.
          enum:
            [
              signature_certificates,
              csf_qr_validation,
              curp,
              lista_nominal,
              commercial_registry,
            ]
        agency_name:
          {
            type: string,
            description: "Nombre completo de la dependencia consultada.",
          }
        subject_type:
          type: string
          description: Sobre quién se realizó la consulta.
          enum: [business, person]
        subject_name:
          {
            type: string,
            nullable: true,
            description: "Nombre del sujeto consultado.",
          }
        subject_identifier:
          type: string
          nullable: true
          description: "Identificador enviado a la dependencia: RFC, CURP, clave de elector o folio mercantil (FME)."
        queried_at:
          type: string
          nullable: true
          description: "Fecha y hora (ISO 8601) de la consulta. null cuando la fuente aún no expone una fecha confiable."
        status:
          type: string
          description: Resultado de la consulta.
          enum: [success, not_found, failed, pending, unknown]
        evidence:
          type: array
          description: "Artefactos de soporte de la consulta (capturas, PDFs o enlaces a la dependencia)."
          items: { $ref: "#/components/schemas/V2ExternalLookupEvidence" }
        data:
          type: object
          additionalProperties: true
          description: >
            Datos extraídos de la consulta, específicos de cada fuente y en snake_case.
            Ver el detalle por ítem en [Items de consultas públicas — KYB México](/guia-devs/uso-kyb/mexico/items-consultas-publicas).

    V2ExternalLookupsData:
      type: array
      description: Arreglo plano de registros de consultas externas, uno por consulta realizada.
      items: { $ref: "#/components/schemas/V2ExternalLookup" }

    V2PublicResponseExternalLookups:
      type: object
      properties:
        success: { type: boolean, enum: [true] }
        data: { $ref: "#/components/schemas/V2ExternalLookupsData" }
        meta: { $ref: "#/components/schemas/V2Meta" }

    FindingsRunConflict:
      type: object
      description: >
        Respuesta `409` de `POST /verifications/{verification-id}/findings/run`
        cuando la corrida de hallazgos no procede en el estado actual de la verificación.


        Este cuerpo usa `error_code`, no el `code` de `ErrorResponse`, a propósito: `code`
        clasifica el error de forma genérica (`VALIDATION_ERROR`, `NOT_FOUND`) y acompaña a
        `success: false`, mientras que `error_code` dice qué condición del negocio impide la
        corrida y se lee para decidir qué hacer a continuación. Ver STYLE_GUIDE, "No duplicar
        significado".
      properties:
        error_code:
          type: string
          enum:
            [not_enabled, pending_documents, already_scheduled, recently_run, up_to_date]
          description: >
            Causa por la que la corrida no procede. `not_enabled`: la cuenta no tiene
            habilitada la Síntesis de Dictamen. `pending_documents`: hay documentos
            requeridos sin subir o aún en procesamiento. `already_scheduled`: ya hay una
            corrida encolada o en ejecución. `recently_run`: hubo una corrida manual hace
            muy poco y aún corre el periodo mínimo entre corridas. `up_to_date`: nada
            cambió desde la última corrida — este endpoint **no** devuelve este código
            (las corridas bajo demanda no exigen que haya cambiado un documento); queda
            en el enum porque el mismo esquema describe las corridas automáticas.
        message:
          type: string
          description: Descripción legible de la causa, pensada para mostrarse tal cual.
        pending_items:
          type: array
          description: >
            Solo cuando `error_code` es `pending_documents`: los items de documento que
            bloquean la corrida (nombre configurado del item o, en su defecto, su tipo).
            Vacía cuando todavía no se sube ningún documento requerido.
          items:
            type: string
        retry_after_seconds:
          type: integer
          description: >
            Solo cuando `error_code` es `recently_run`: segundos que faltan para poder
            pedir otra corrida. Es el tiempo restante, no la duración total del
            periodo mínimo entre corridas.
          example: 240
      required:
        - error_code
        - message
    ErrorResponse:
      type: object
      properties:
        success:
          type: boolean
          example: false
        message:
          type: string
          example: "Descripción breve y accionable del error"
        code:
          oneOf:
            - type: string
              enum:
                [
                  VALIDATION_ERROR,
                  BAD_REQUEST,
                  UNAUTHORIZED,
                  FORBIDDEN,
                  NOT_FOUND,
                  CONFLICT,
                  DUPLICATE_RESOURCE,
                  INTERNAL_SERVER_ERROR,
                ]
            - type: string
              description: Código de dominio específico (p.ej., items_not_provided)
          example: VALIDATION_ERROR
        timestamp:
          type: string
          format: date-time
          example: "2025-01-01T12:34:56.000Z"
    PublicVerification:
      type: object
      properties:
        country: { type: string }
        created_at: { type: string }
        updated_at: { type: string }
        account_id: { type: string }
        id: { type: string }
        items:
          type: array
          items:
            $ref: "#/components/schemas/PublicVerificationItem"
          nullable: true
        metadata:
          type: object
          additionalProperties: true
          nullable: true
        status: { type: string }
        documents_status: { type: string, nullable: true }
        tag: { type: string, nullable: true }
        email: { type: string, nullable: true }
        signatory_email: { type: string, nullable: true }
        tax_id: { type: string, nullable: true }
        flow_id: { nullable: true }
        notification_hint: { type: string, nullable: true }
        validation_options:
          type: object
          additionalProperties: true
          nullable: true
        details_url: { type: string }
        onboarding_url: { type: string }
        business_name: { type: string, nullable: true }
        friendly_name:
          type: string
          nullable: true
          description: >
            Nombre descriptivo asignado por el usuario al crear la verificación. Permite
            identificar fácilmente la empresa o persona asociada a la verificación.
          example: "Empresa ACME S.A. de C.V."
        comments_legal_review:
          type: array
          items: { type: string }
          nullable: true
        access_token: { type: string }
        options:
          type: object
          properties:
            requires_id_validation: { type: boolean }
          nullable: true
        created_by: { type: string, nullable: true }
        onboarding_terms_and_conditions:
          type: object
          additionalProperties: true
          nullable: true
        lookups_report:
          type: object
          nullable: true
          description: >
            Reporte PDF de auditoría de las consultas públicas externas (SAT, RENAPO, INE, SIGER).
            Presente solo cuando existe un reporte para la verificación; se omite en caso contrario.
            Ver [Consultas públicas externas](/guia-devs/monitorear/consultas-publicas-externas).
          properties:
            url:
              type: string
              description: >
                URL firmada para descargar el PDF (se sirve como adjunto). Es de corta duración y se
                regenera en cada llamada; ver el detalle de uso en
                [Consultas públicas externas](/guia-devs/monitorear/consultas-publicas-externas).
            generated_at:
              type: string
              description: "Fecha y hora (ISO 8601) en que se generó el reporte."
        _kind:
          type: string
          enum: [public_verification, verification]

    CustomItemTypeItemValue:
      type: object
      description: |
        `item_value` de un ítem cuyo `item_type` es un tipo de ítem personalizado (prefijo `cit_`).

        No lleva llaves `cp_<prompt_id>`: ese prefijo es exclusivo de las [extracciones personalizadas](/producto/guias/extracciones-personalizadas) sobre tipos de documento estándar. Aquí los resultados viven en `pipeline`, con un paso por cada proceso configurado en el tipo, identificado por su `process_reference`. Ver [Tipos de ítem personalizados](/producto/guias/tipos-de-item-personalizados#donde-salen-los-resultados).
      properties:
        pipeline:
          type: object
          description: Resultado de cada proceso del tipo para este ítem.
          properties:
            validation:
              type: array
              description: Un paso por regla de validación del tipo. Array vacío si el tipo no tiene validaciones.
              items:
                $ref: "#/components/schemas/CustomItemTypeValidationStep"
            extraction:
              type: array
              description: Un paso por proceso de extracción del tipo. Array vacío si el tipo no tiene extracciones.
              items:
                $ref: "#/components/schemas/CustomItemTypeExtractionStep"
        current_stage:
          type: string
          description: |
            Etapa del pipeline interno en la que quedó el ítem. Es informativa y su lista de valores no es estable: para saber si el ítem terminó usa `item_status` junto con `item_error`.
          example: "extraction"

    CustomItemTypeExtractionStep:
      type: object
      description: Resultado de un proceso de extracción del tipo para este ítem.
      properties:
        process_reference:
          type: string
          description: Etiqueta del proceso de extracción, la misma que definiste al crearlo. Única dentro del tipo.
          example: "extraer_datos_contrato"
        executed:
          type: boolean
          description: "`true` cuando el proceso llegó a ejecutarse para este ítem."
          example: true
        execution_result:
          type: string
          enum: ["success", "error"]
          description: Resultado de la ejecución. Solo aparece cuando `executed` es `true`.
          example: "success"
        value:
          type: object
          additionalProperties: true
          nullable: true
          description: |
            JSON extraído. Sus claves son las `properties` del `json_schema` de la versión que se ejecutó. Es `null` cuando el proceso no se ejecutó o terminó en error.

            Trébol elimina de este objeto, en todos los niveles, las claves que empiezan por `paragraphs_` o `parrafos_` (trazas internas de citas).

    CustomItemTypeValidationStep:
      type: object
      description: Resultado de una regla de validación del tipo para este ítem.
      properties:
        process_reference:
          type: string
          description: Etiqueta de la regla de validación, la misma que definiste al crearla. Única dentro del tipo.
          example: "validar_firmas"
        executed:
          type: boolean
          description: "`true` cuando la regla llegó a evaluarse para este ítem."
          example: true
        execution_result:
          type: boolean
          description: "`true` si la regla se cumplió, `false` si no. Solo aparece cuando `executed` es `true`."
          example: true
        value:
          type: object
          nullable: true
          description: Detalle de la evaluación de la regla. Es `null` cuando la regla no se evaluó o la llamada al validador falló.
          properties:
            identifier:
              description: Identificador interno de la regla evaluada.
              oneOf:
                - type: string
                - type: number
              example: "activeVersionId_87"
            validation_result:
              type: boolean
              description: Si la regla se cumplió.
              example: true
            explanation:
              type: string
              description: Explicación en texto de por qué la regla se cumplió o no.
            variable_name:
              type: string
              description: Nombre del dato del documento que la regla comparó.
            variable_value:
              type: string
              description: Valor encontrado en el documento.
            reference_value:
              type: string
              description: Valor de referencia contra el que se comparó.
            applied_rule:
              type: string
              description: Regla aplicada, tal como la interpretó el validador.

    VerificationFindings:
      type: object
      nullable: true
      description: >
        Hallazgos de la Síntesis de Dictamen.

        Solo lo devuelve `GET /verifications/{verification-id}`, donde siempre está presente.
        El listado `GET /verifications` no incluye este campo: para leer los hallazgos de una
        verificación, consúltala por su ID.

        Es `null` mientras la revisión no se haya ejecutado para esa verificación. Un `items`
        vacío es distinto: significa que la revisión sí corrió y no encontró nada.
      required: [items, computed_at, source]
      properties:
        items:
          type: array
          description: >
            Lista de hallazgos. Vacía cuando la revisión se ejecutó y no encontró problemas.
          items:
            $ref: "#/components/schemas/VerificationFinding"
        computed_at:
          type: string
          format: date-time
          nullable: true
          description: >
            Fecha y hora (ISO 8601) de la corrida que produjo los hallazgos. Es `null` en
            verificaciones antiguas, anteriores a que se registrara este dato.
        source:
          type: string
          enum: [provisional, final]
          description: >
            Origen de la revisión. `provisional`: Trébol la calcula antes de completarse la
            verificación, con un modelo más rápido, y una corrida final puede reemplazarla.
            `final`: Trébol la calcula al completarse la verificación.

    VerificationFinding:
      type: object
      description: Un hallazgo individual de la Síntesis de Dictamen.
      properties:
        severity:
          type: string
          enum: [high, medium, low]
          description: Severidad del hallazgo.
        message:
          type: string
          description: Descripción del hallazgo en lenguaje natural.
        missing_field:
          type: string
          description: >
            Campo o dato faltante al que se refiere el hallazgo, cuando aplica (por ejemplo
            `shareholders`). Se omite cuando el hallazgo no corresponde a un dato faltante.
      required: [severity, message]

    VerificationItem:
      type: object
      properties:
        id: { type: number }
        item_status: { type: string }
        item_order: { type: number }
        item_type: { type: string }
        item_value:
          description: |
            Estructura depende de `item_type`. Ver guía en /guia-devs/respuestas-por-tipo-de-item.

            Además de los campos propios del tipo, incluye una llave `cp_<prompt_id>` por cada extracción personalizada con resultado para ese ítem, donde `prompt_id` es el identificador editable de la extracción. Ver [Extracciones personalizadas](/producto/guias/extracciones-personalizadas).

            Ese prefijo solo aplica a tipos de documento estándar. Un ítem de un tipo de ítem personalizado (`item_type` con prefijo `cit_`) nunca lleva llaves `cp_`: sus resultados viven en `pipeline`, con la forma del schema `CustomItemTypeItemValue`. Ver [Tipos de ítem personalizados](/producto/guias/tipos-de-item-personalizados#donde-salen-los-resultados).
          type: object
          additionalProperties: true
        item_error:
          type: string
          nullable: true
          description: |
            Campo opcional que indica errores públicos relacionados con el procesamiento del ítem. Su valor depende del `item_type` que produjo el error.

            **Comunes a ítems documentales**
            - `password_protected_pdf`: el PDF está protegido con contraseña y no se envió `file_password`. Reenvía el archivo con `options.file_password`.
            - `invalid_file_password`: se envió `file_password` pero el PDF la rechazó. Reenvía el archivo con la contraseña correcta.
            - `get_input_file_info_failed`: falló la obtención de información del archivo de entrada.

            **Específicos de `doc_splitter`** (ver [guía](/producto/guias/doc-splitter) para el listado completo)
            - `unsupported_file_type`: el archivo no es un PDF.
            - `unknown_custom_item_type` / `misconfigured_custom_item_type`: `allowed_item_types` o `client_item_type` referencia un tipo personalizado (`cit_*`) que no existe o no está listo.
            - `no_splits_returned`: el análisis no identificó ningún documento en el PDF.
            - `pdf_slice_failed`: no se pudo leer o recortar el PDF (archivo corrupto o error de descarga del original).
            - `pdf_slice_upload_failed`: se recortaron los sub-PDFs pero falló la subida de al menos uno.
            - `doc_splitter_request_failed`: falló la llamada al servicio de análisis (OCR o AI). Reintentar suele resolverlo.

            **Específicos de `doc_validation`**
            - `invalid_document_type`: el documento no corresponde al `client_item_type` esperado.
            - `ruleset_validation_failed`: al menos una regla del `ruleset` no se cumplió.

            Trata este campo como un `string` opaco: además de los códigos anteriores puede llegar con otros valores para ítems específicos (por ejemplo `prevalidation_failed` en `csf_mx`) o, en errores inesperados, con un mensaje libre en inglés.
        item_internal_status: { type: string, nullable: true }
        item_options:
          type: object
          additionalProperties: true
          nullable: true
        item_ui_options:
          type: object
          additionalProperties: true
          nullable: true
        validation_result:
          type: object
          additionalProperties: true
          nullable: true
        user_event_completed_at: { type: string, nullable: true }
        user_event_name: { type: string, nullable: true }
        user_event_reason: { type: string, nullable: true }
        tag: { type: string, nullable: true }
        item_scope: { type: string, nullable: true }
        original_file_url: { type: string, nullable: true }
        verification_id: { type: number, nullable: true }
        created_at: { type: string, nullable: true }
        updated_at: { type: string, nullable: true }
    PublicVerificationItem:
      type: object
      properties:
        id: { type: number }
        item_status: { type: string }
        item_order: { type: number }
        item_type: { type: string }
        item_value:
          description: |
            Estructura depende de `item_type`. Ver guía en /guia-devs/respuestas-por-tipo-de-item.

            Además de los campos propios del tipo, incluye una llave `cp_<prompt_id>` por cada extracción personalizada con resultado para ese ítem, donde `prompt_id` es el identificador editable de la extracción. Ver [Extracciones personalizadas](/producto/guias/extracciones-personalizadas).

            Ese prefijo solo aplica a tipos de documento estándar. Un ítem de un tipo de ítem personalizado (`item_type` con prefijo `cit_`) nunca lleva llaves `cp_`: sus resultados viven en `pipeline`, con la forma del schema `CustomItemTypeItemValue`. Ver [Tipos de ítem personalizados](/producto/guias/tipos-de-item-personalizados#donde-salen-los-resultados).
          type: object
          additionalProperties: true
        item_error:
          type: string
          nullable: true
          description: |
            Campo opcional que indica errores públicos relacionados con el procesamiento del ítem. Su valor depende del `item_type` que produjo el error.

            **Comunes a ítems documentales**
            - `password_protected_pdf`: el PDF está protegido con contraseña y no se envió `file_password`. Reenvía el archivo con `options.file_password`.
            - `invalid_file_password`: se envió `file_password` pero el PDF la rechazó. Reenvía el archivo con la contraseña correcta.
            - `get_input_file_info_failed`: falló la obtención de información del archivo de entrada.

            **Específicos de `doc_splitter`** (ver [guía](/producto/guias/doc-splitter) para el listado completo)
            - `unsupported_file_type`: el archivo no es un PDF.
            - `unknown_custom_item_type` / `misconfigured_custom_item_type`: `allowed_item_types` o `client_item_type` referencia un tipo personalizado (`cit_*`) que no existe o no está listo.
            - `no_splits_returned`: el análisis no identificó ningún documento en el PDF.
            - `pdf_slice_failed`: no se pudo leer o recortar el PDF (archivo corrupto o error de descarga del original).
            - `pdf_slice_upload_failed`: se recortaron los sub-PDFs pero falló la subida de al menos uno.
            - `doc_splitter_request_failed`: falló la llamada al servicio de análisis (OCR o AI). Reintentar suele resolverlo.

            **Específicos de `doc_validation`**
            - `invalid_document_type`: el documento no corresponde al `client_item_type` esperado.
            - `ruleset_validation_failed`: al menos una regla del `ruleset` no se cumplió.

            Trata este campo como un `string` opaco: además de los códigos anteriores puede llegar con otros valores para ítems específicos (por ejemplo `prevalidation_failed` en `csf_mx`) o, en errores inesperados, con un mensaje libre en inglés.
        item_internal_status: { type: string, nullable: true }
        item_options:
          type: object
          additionalProperties: true
          nullable: true
          properties:
            upload_url:
              type: string
              format: uri
              description: URL firmada temporal para subir el archivo del item mediante PUT. Después de subirlo, confirma con options.uploaded_file en PUT /verification-items/{id}.
        item_ui_options:
          type: object
          additionalProperties: true
          nullable: true
        validation_result:
          type: object
          additionalProperties: true
          nullable: true
        user_event_completed_at: { type: string, nullable: true }
        user_event_name: { type: string, nullable: true }
        user_event_reason: { type: string, nullable: true }
        tag: { type: string, nullable: true }
        item_scope: { type: string, nullable: true }
        original_file_url: { type: string, nullable: true }
        citations:
          type: object
          description: |
            Presente solo cuando se llamó con `?with_citations=true` y el item es de tipo acta. Contiene la URL firmada (CloudFront) al artifact de coordenadas en S3. Ver [Coordenadas de citas](/guia-devs/referencia/coordenadas-citas).
          properties:
            url:
              type: string
              format: uri
              description: |
                URL firmada y temporal. Descarga el JSON cuanto antes; si caduca, vuelve a llamar al endpoint con el flag para obtener una nueva. Si el artifact aún no se horneó para esta verificación, no se devuelve la llave citations.
              example: "https://files.gotrebol.com/{verification_id}/citations/sources/{item_id}.json?Expires=…&Signature=…"
          required:
            - url
    VerificationSummary:
      type: object
      properties:
        id:
          type: string
          description: ID de la verificación.
        tag:
          type: string
          description: Etiqueta de la verificación.
        status:
          type: string
          description: Estado de la verificación.
      required: [id, tag, status]

    CompanyDetailsField:
      type: object
      properties:
        value:
          description: Valor extraído para el campo. Puede ser string, number, booleano u objeto con estructura específica.
          oneOf:
            - type: string
            - type: number
            - type: boolean
            - type: object
            - type: array
        businessType:
          type: string
          nullable: true
        sourceLines:
          type: array
          items: { type: string }
          nullable: true
        validation:
          type: object
          nullable: true
      nullable: true

    CompanyDetailsResponse:
      type: object
      properties:
        fields:
          $ref: "#/components/schemas/CompanyDetailsFields"
        verification:
          $ref: "#/components/schemas/VerificationSummary"
    CompanyConstitutiveData:
      type: object
      properties:
        constitutiveBusinessName: { type: string }
        constitutiveActaNumber: { type: string }
        constitutiveNotaryNumber: { type: string }
        constitutiveNotaryName: { type: string }
        constitutiveBusinessType: { type: string }
        constitutiveFolioNumber: { type: string }
        constitutiveFolioDate: { type: string }
        constitutiveFolioInscriptionDate: { type: string }

    AddressDisaggregated:
      type: object
      properties:
        street_type: { type: string }
        street_name: { type: string }
        external_number: { type: string }
        internal_number: { type: string }
        neighborhood: { type: string }
        district: { type: string }
        state: { type: string }
        post_code: { type: string }

    DocumentProps:
      type: object
      properties:
        documentType: { type: string }
        enterpriseName: { type: string, nullable: true }
        matchesEnterpriseName: { type: boolean, nullable: true }
        documentNumber: { type: string, nullable: true }
        documentDate: { type: string, format: date-time, nullable: true }
        notaryPlace: { type: string, nullable: true }
        notaryNumber: { type: string, nullable: true }
        notaryName: { type: string, nullable: true }
        state: { type: string }
        idType: { type: string, nullable: true }
        documentUrl: { type: string, format: uri, nullable: true }
        isDuplicated: { type: boolean, nullable: true }
        isIncomplete: { type: boolean, nullable: true }
        itemId: { type: number }

    PfaeIdentity:
      type: object
      properties:
        claveElector: { type: string, nullable: true }
        dueDate: { type: string, format: date-time, nullable: true }
        curp: { type: string, nullable: true }
        nacionalidad: { type: string, nullable: true }

    SigerValidationValue:
      type: object
      properties:
        folioNumberMatch: { type: string, nullable: true }
        mostRecentActaUploaded: { type: boolean }
        sigerValue:
          type: object
          description: Objeto SIGER serializado

    CompanyDetailsFieldString:
      allOf:
        - $ref: "#/components/schemas/CompanyDetailsField"
        - type: object
          properties:
            value:
              type: string

    CompanyDetailsFieldBoolean:
      allOf:
        - $ref: "#/components/schemas/CompanyDetailsField"
        - type: object
          properties:
            value:
              type: boolean

    CompanyDetailsFieldConstitutive:
      allOf:
        - $ref: "#/components/schemas/CompanyDetailsField"
        - type: object
          properties:
            value:
              $ref: "#/components/schemas/CompanyConstitutiveData"

    CompanyDetailsFieldAddressDisaggregated:
      allOf:
        - $ref: "#/components/schemas/CompanyDetailsField"
        - type: object
          properties:
            value:
              $ref: "#/components/schemas/AddressDisaggregated"

    CompanyDetailsFieldDocuments:
      allOf:
        - $ref: "#/components/schemas/CompanyDetailsField"
        - type: object
          properties:
            value:
              type: array
              items:
                $ref: "#/components/schemas/DocumentProps"

    CompanyDetailsFieldPfaeIdentity:
      allOf:
        - $ref: "#/components/schemas/CompanyDetailsField"
        - type: object
          properties:
            value:
              $ref: "#/components/schemas/PfaeIdentity"

    CompanyDetailsFieldSigerValidation:
      allOf:
        - $ref: "#/components/schemas/CompanyDetailsField"
        - type: object
          properties:
            value:
              $ref: "#/components/schemas/SigerValidationValue"

    CompanyDetailsFields:
      type: object
      properties:
        businessName:
          {
            $ref: "#/components/schemas/CompanyDetailsFieldString",
            nullable: true,
          }
        businessConstitutiveData:
          {
            $ref: "#/components/schemas/CompanyDetailsFieldConstitutive",
            nullable: true,
          }
        businessType:
          {
            $ref: "#/components/schemas/CompanyDetailsFieldString",
            nullable: true,
          }
        businessRegistrationDate:
          {
            $ref: "#/components/schemas/CompanyDetailsFieldString",
            nullable: true,
          }
        businessDuration:
          {
            $ref: "#/components/schemas/CompanyDetailsFieldString",
            nullable: true,
          }
        businessFiscalStatus:
          {
            $ref: "#/components/schemas/CompanyDetailsFieldString",
            nullable: true,
          }
        businessTaxId:
          {
            $ref: "#/components/schemas/CompanyDetailsFieldString",
            nullable: true,
          }
        businessAddress:
          {
            $ref: "#/components/schemas/CompanyDetailsFieldString",
            nullable: true,
          }
        businessComercialAddress:
          {
            $ref: "#/components/schemas/CompanyDetailsFieldString",
            nullable: true,
          }
        businessFiscalAddress:
          {
            $ref: "#/components/schemas/CompanyDetailsFieldString",
            nullable: true,
          }
        businessFiscalAddressDisaggregated:
          {
            $ref: "#/components/schemas/CompanyDetailsFieldAddressDisaggregated",
            nullable: true,
          }
        businessLegalAddress:
          {
            $ref: "#/components/schemas/CompanyDetailsFieldString",
            nullable: true,
          }
        businessCreditorAbility:
          {
            $ref: "#/components/schemas/CompanyDetailsFieldBoolean",
            nullable: true,
          }
        businessAssetPledging:
          {
            $ref: "#/components/schemas/CompanyDetailsFieldBoolean",
            nullable: true,
          }
        businessGuarantorAbility:
          {
            $ref: "#/components/schemas/CompanyDetailsFieldBoolean",
            nullable: true,
          }
        businessPurposeCreditLimit:
          {
            $ref: "#/components/schemas/CompanyDetailsFieldString",
            nullable: true,
          }
        businessMainActivity:
          {
            $ref: "#/components/schemas/CompanyDetailsFieldString",
            nullable: true,
          }
        businessRequiresLegalReview:
          {
            $ref: "#/components/schemas/CompanyDetailsFieldBoolean",
            nullable: true,
          }
        businessFolioNumber:
          {
            $ref: "#/components/schemas/CompanyDetailsFieldString",
            nullable: true,
          }
        businessDocuments:
          {
            $ref: "#/components/schemas/CompanyDetailsFieldDocuments",
            nullable: true,
          }
        pfaeName:
          {
            $ref: "#/components/schemas/CompanyDetailsFieldString",
            nullable: true,
          }
        pfaeTaxId:
          {
            $ref: "#/components/schemas/CompanyDetailsFieldString",
            nullable: true,
          }
        pfaeType:
          {
            $ref: "#/components/schemas/CompanyDetailsFieldString",
            nullable: true,
          }
        pfaeFiscalStatus:
          {
            $ref: "#/components/schemas/CompanyDetailsFieldString",
            nullable: true,
          }
        pfaeRegistrationDate:
          {
            $ref: "#/components/schemas/CompanyDetailsFieldString",
            nullable: true,
          }
        pfaeAddress:
          {
            $ref: "#/components/schemas/CompanyDetailsFieldString",
            nullable: true,
          }
        pfaeMainActivity:
          {
            $ref: "#/components/schemas/CompanyDetailsFieldString",
            nullable: true,
          }
        pfaeComercialAddress:
          {
            $ref: "#/components/schemas/CompanyDetailsFieldString",
            nullable: true,
          }
        pfaeFiscalAddress:
          {
            $ref: "#/components/schemas/CompanyDetailsFieldString",
            nullable: true,
          }
        pfaeDocuments:
          {
            $ref: "#/components/schemas/CompanyDetailsFieldDocuments",
            nullable: true,
          }
        pfaeIdentity:
          {
            $ref: "#/components/schemas/CompanyDetailsFieldPfaeIdentity",
            nullable: true,
          }
        sigerValidation:
          {
            $ref: "#/components/schemas/CompanyDetailsFieldSigerValidation",
            nullable: true,
          }

    CompanyDocumentsResponse:
      type: object
      properties:
        documents:
          type: array
          items:
            type: object
            properties:
              label: { type: string }
              url: { type: string, format: uri }
            required: [label, url]
        verification:
          $ref: "#/components/schemas/VerificationSummary"

    CompanyPeopleResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            key_people:
              type: array
              description: Personas clave (con roles y poderes)
              items:
                $ref: "#/components/schemas/KeyPeopleItem"
            full_list:
              type: array
              description: Personas detectadas sin agrupar por rol
              items:
                $ref: "#/components/schemas/PeopleItem"
            proxies:
              type: array
              description: Grupo dinámico de apoderados detectados en actas
              items:
                $ref: "#/components/schemas/SignatoryGroupItem"
            auditors:
              type: array
              description: Grupo dinámico de auditores detectados en actas
              items:
                $ref: "#/components/schemas/SignatoryGroupItem"
            board_members:
              type: array
              description: Grupo dinámico de miembros del consejo detectados en actas
              items:
                $ref: "#/components/schemas/SignatoryGroupItem"
          additionalProperties:
            type: array
            items:
              $ref: "#/components/schemas/SignatoryGroupItem"
        verification:
          $ref: "#/components/schemas/VerificationSummary"
    SourceInfo:
      type: object
      properties:
        itemId: { type: number }
        subjectId: { type: number, nullable: true }
        documentUrl: { type: string, format: uri, nullable: true }
        itemType: { type: string }
        documentDate: { type: string, nullable: true }
        documentNumber: { type: string, nullable: true }
        entityName: { type: string, nullable: true }
        extraFields:
          type: object
          properties:
            notaryCity: { type: string, nullable: true }
            notaryState: { type: string, nullable: true }
            notaryName: { type: string, nullable: true }
            notaryNumber: { type: string, nullable: true }
            folioNumber: { type: string, nullable: true }
            folioDate: { type: string, nullable: true }
            folioInscriptionDate: { type: string, nullable: true }
            folioDataSource: { type: string, nullable: true }

    RolePower:
      type: object
      properties:
        power_name: { type: string }
        duration: { type: number }
        has_power: { type: boolean }
        signature_type: { type: string, nullable: true }
        has_limits: { type: boolean }
        limits_description: { type: string }
        due_date: { type: string, format: date-time, nullable: true }
        due_date_source:
          { type: string, enum: [legal, document], nullable: true }

    KeyPeopleRole:
      type: object
      properties:
        role_name: { type: string }
        group_name: { type: string }
        event:
          type: string
          description: Evento que originó el rol. Un rol `mentioned` indica que el acta menciona a la persona con ese rol. Solo se incluye si al menos un elemento de `powers` tiene `has_power` en `true`.
        duration: { type: number }
        powers:
          type: array
          items: { $ref: "#/components/schemas/RolePower" }
        sourceLines:
          type: array
          items: { type: string }
        source: { $ref: "#/components/schemas/SourceInfo" }
        powers_source:
          { $ref: "#/components/schemas/SourceInfo", nullable: true }
        powers_due_date: { type: string, format: date-time, nullable: true }
        powers_due_date_source:
          { type: string, enum: [legal, document], nullable: true }

    IdentityMatch:
      type: object
      description: Coincidencias con documentos de identidad (INE/Pasaporte)
      additionalProperties: true

    FiscalMatch:
      type: object
      description: Coincidencias con CSF (individual)
      additionalProperties: true

    AddressMatch:
      type: object
      description: Coincidencias con direcciones de comprobantes/estados de cuenta
      additionalProperties: true

    KeyPeopleItem:
      type: object
      properties:
        names: { type: string }
        idNumber: { type: string, nullable: true }
        id_number_rfc: { type: string, nullable: true }
        gender: { type: string, nullable: true }
        nationality: { type: string, nullable: true }
        birthDate: { type: string, nullable: true }
        birthEntity: { type: string, nullable: true }
        roles:
          type: array
          items: { $ref: "#/components/schemas/KeyPeopleRole" }
        identity: { $ref: "#/components/schemas/IdentityMatch" }
        fiscal: { $ref: "#/components/schemas/FiscalMatch" }
        address: { $ref: "#/components/schemas/AddressMatch" }
        ubo_forms:
          type: object
          additionalProperties: true
          nullable: true
        externalIdentities:
          type: object
          additionalProperties: true
          nullable: true
        scope:
          type: array
          items: { type: string }
          nullable: true
        peopleId: { type: number }
        ai_suggested: { type: boolean, nullable: true }
        human_reviewed: { type: boolean, nullable: true }

    PeopleItem:
      type: object
      properties:
        names: { type: string }
        idNumber: { type: string, nullable: true }
        id_number_rfc: { type: string, nullable: true }
        gender: { type: string, nullable: true }
        nationality: { type: string, nullable: true }
        birthDate: { type: string, nullable: true }
        birthEntity: { type: string, nullable: true }
        identity: { $ref: "#/components/schemas/IdentityMatch" }
        fiscal: { $ref: "#/components/schemas/FiscalMatch" }
        address: { $ref: "#/components/schemas/AddressMatch" }
        ubo_forms:
          type: object
          additionalProperties: true
          nullable: true
        externalIdentities:
          type: object
          additionalProperties: true
          nullable: true
        scope:
          type: array
          items: { type: string }
          nullable: true
        peopleId: { type: number }
        ai_suggested: { type: boolean, nullable: true }
        human_reviewed: { type: boolean, nullable: true }

    SignatoryGroupItem:
      type: object
      properties:
        roleId: { type: string, nullable: true }
        names: { type: string }
        idNumber: { type: string }
        id_number_rfc: { type: string, nullable: true }
        idType: { type: string }
        roleName: { type: string }
        event:
          type: string
          description: Evento que originó el rol. `signatory_groups` incluye también las menciones (`mentioned`) sin poderes.
        duration: { type: number }
        sourceLines:
          type: array
          items: { type: string }
        source: { $ref: "#/components/schemas/SourceInfo" }
        type: { type: string, nullable: true }
        fiscal:
          type: object
          additionalProperties: true
        identity:
          type: object
          additionalProperties: true
        address:
          type: object
          additionalProperties: true
        externalIdentities:
          type: object
          additionalProperties: true
          nullable: true
        ubo_forms:
          type: object
          additionalProperties: true
          nullable: true
        folioNumber: { type: string, nullable: true }
        folioDate: { type: string, nullable: true }
        folioInscriptionDate: { type: string, nullable: true }

    CompanyShareholdersResponse:
      type: object
      properties:
        shareholders:
          type: array
          description: Lista de accionistas detectados en las actas
          items:
            $ref: "#/components/schemas/ShareholderItem"
        capital:
          $ref: "#/components/schemas/CompanyCapital"
        source:
          $ref: "#/components/schemas/ShareholdersSource"
        shareholders_unavailable_reason:
          type: string
          nullable: true
          enum:
            ["business_type_without_shareholders", "pending_extraction", null]
          description: |
            Por qué `shareholders` viene vacío: `business_type_without_shareholders` cuando el tipo de sociedad no tiene accionistas y la lista vacía es final, `pending_extraction` cuando hay un acta en extracción, `null` cuando no hay motivo que reportar. Los dos campos siempre están presentes: lo opcional es el valor, no su presencia. Nunca se omiten del objeto, ni siquiera cuando hay accionistas — en ese caso `shareholders_unavailable_reason` llega en `null`. Campo aditivo, disponible desde el 20 de agosto de 2026. Ver [Motivo cuando la lista de accionistas viene vacía](/guia-devs/uso-kyb/mexico/accionistas#motivo-sin-accionistas).
          example: null
        business_type:
          type: string
          nullable: true
          description: |
            Tipo de sociedad del que Trébol derivó el motivo, tal como está escrito en el documento. Campo aditivo, disponible desde el 20 de agosto de 2026.
          example: "SOCIEDAD ANONIMA DE CAPITAL VARIABLE"
        verification:
          $ref: "#/components/schemas/VerificationSummary"

    ShareholderItem:
      type: object
      properties:
        id: { type: number }
        currency: { type: string }
        fixed_shares: { type: string }
        fixed_value: { type: string }
        id_number: { type: string }
        id_number_rfc: { type: string, nullable: true }
        id_type: { type: string }
        name: { type: string }
        nationality: { type: string }
        total_shares: { type: string }
        total_value: { type: string }
        type: { type: string }
        variable_shares: { type: string }
        variable_value: { type: string }
        share_percentage: { type: number }
        aml_validated_at: { type: string, nullable: true }
        aml_validation_status: { type: string, nullable: true }
        aml_risk_category:
          type: array
          items:
            type: string
            enum:
              [
                PEP,
                Politician,
                Law Enforcement,
                Regulatory Enforcement,
                Sanctions,
                Gatekeepers,
                Adverse Information,
              ]
        aml_data:
          type: array
          items: { type: object }
          nullable: true
        identity: { $ref: "#/components/schemas/IdentityMatch" }
        fiscal: { $ref: "#/components/schemas/FiscalMatch" }
        address: { $ref: "#/components/schemas/AddressMatch" }
        ubo_forms:
          type: object
          additionalProperties: true
          nullable: true
        externalIdentities:
          type: object
          additionalProperties: true
          nullable: true
        gender: { type: string, nullable: true }
        birthDate: { type: string, nullable: true }
        birthEntity: { type: string, nullable: true }

    CompanyCapital:
      type: object
      properties:
        fixedValue: { type: number }
        fixedShares: { type: number }
        fixedValueCurrency: { type: string }
        variableValue: { type: number }
        variableShares: { type: number }
        variableValueCurrency: { type: string }
        totalValue: { type: number }
        totalShares: { type: number }
        totalValueCurrency: { type: string }

    ShareholdersSource:
      type: object
      properties:
        type: { type: string }
        source_date: { type: string, nullable: true }
        business_name: { type: string }
        acta_number: { type: string }
        acta_city: { type: string, nullable: true }
        acta_state: { type: string, nullable: true }
        folio_date: { type: string, nullable: true }
        folio_inscription_date: { type: string, nullable: true }
        folio_number: { type: string, nullable: true }
        folio_data_source:
          type: object
          properties:
            folioNumberSource: { type: string, enum: [ac_mx, siger, "N/A"] }
            folioDateSource: { type: string, enum: [ac_mx, siger, "N/A"] }
          nullable: true
        notary_name: { type: string }
        notary_number: { type: string }
        document_url: { type: string, format: uri, nullable: true }
        item_id: { type: number, nullable: true }
        item_type: { type: string, nullable: true }
        information_source: { type: string, nullable: true }

    CompanySourcesResponse:
      type: object
      properties:
        data:
          type: array
          description: Lista de fuentes internas (items) que alimentan la verificación
          items:
            $ref: "#/components/schemas/VerificationSource"
        verification:
          $ref: "#/components/schemas/VerificationSummary"

    VerificationSource:
      type: object
      properties:
        id: { type: number }
        type: { type: string, description: "item_type" }
        entityName: { type: string, nullable: true }
        documentNumber: { type: string, nullable: true }
        documentDate: { type: string, nullable: true }
        documentMetadata:
          type: object
          additionalProperties: true
          nullable: true
        originalFileUrl: { type: string, format: uri, nullable: true }
        userEventCompletedAt:
          { type: string, format: date-time, nullable: true }
        userEventName: { type: string, nullable: true }
        invalidated: { type: boolean }
        options:
          type: object
          additionalProperties: true
          nullable: true
        fieldConfidences:
          type: object
          additionalProperties: true
          nullable: true
        validationResult:
          type: object
          additionalProperties: true
          nullable: true
        classifiedAt: { type: string, nullable: true }
        itemValue:
          description: Solo presente para types especiales (siger, forms, public_sat_signatures, siger_shareholders)
          nullable: true
        itemStatus: { type: string }
        isDuplicateItem: { type: boolean, nullable: true }
        assemblyMinute:
          type: object
          additionalProperties: true
          nullable: true
    VerificationWithFlowId:
      title: Con Flow ID
      type: object
      required:
        - country
        - tag
        - flow_id
        - tax_id
      properties:
        flow_id:
          type: string
          description: |
            Identificador para el flujo de verificación específico, este creara una verificacion con los items y validaciones ya definidas en el flujo.
            No es necesario incluir el campo `items` si se usa este campo.
          example: "documents-v2"
        country:
          type: string
          description: El código del país en formato ISO 3166-1 alfa-2. Actualmente soportado solo para México ('mx').
        tag:
          type: string
          description: Una etiqueta única que identifica la verificación.
        tax_id:
          type: string
          description: El número de identificación fiscal de la empresa.
        friendly_name:
          type: string
          description: |
            Nombre descriptivo de la empresa o persona que será procesada en la verificación.
            Este campo es opcional y se recomienda usarlo para facilitar la búsqueda e identificación de verificaciones,
            ya que el sistema no siempre puede extraer automáticamente el nombre de la empresa o persona a partir de los documentos cargados.
          example: "Empresa ACME S.A. de C.V."
        email:
          type: string
          format: email
          description: Dirección de correo electrónico del cliente que solicita el onboarding.
          example: "jonh_doe@gmail.com"
        metadata:
          type: object
          description: Información adicional o metadatos asociados a la verificación.
          additionalProperties: true
        options:
          type: object
          description: Opciones adicionales para la verificación.
          properties:
            creator_email:
              type: string
              format: email
              description: Email del creador de la verificacion, el usuario empresarial.
    ClientItemType:
      type: string
      description: Especificacion del tipo de item segun el cliente. Consulta los valores disponibles en [Tipos de ítem](/guia-devs/referencia/tipos-item)
    VerificationWithItems:
      title: Con items predefinidos por el usuario
      type: object
      required:
        - country
        - tag
        - items
      properties:
        friendly_name:
          type: string
          description: |
            Nombre descriptivo de la empresa o persona que será procesada en la verificación.
            Este campo es opcional y se recomienda usarlo para facilitar la búsqueda e identificación de verificaciones,
            ya que el sistema no siempre puede extraer automáticamente el nombre de la empresa o persona a partir de los documentos cargados.
          example: "Juan Pérez López"
        items:
          type: array
          description: |
            Una lista de ítems o documentos que serán verificados, cada item debe tener un tipo y opciones.
            Esta opcion se utiliza cuando se quiere crear una verificacion con items personalizados, sin un flujo predefinido.
          items:
            type: object
            required:
              - type
              - options
            properties:
              type:
                type: string
                description: El tipo de documento o ítem a verificar.
              options:
                type: object
                description: |
                  Opciones adicionales para el ítem. Para el origen del archivo envía `file_url` (URL descargable); si lo omites, Trébol devuelve una `upload_url` presignada (ver [flujo de carga directa](/guia-devs/crear-verificaciones/via-api/carga-directa)). Este flujo también aplica a `doc_splitter`: sube el archivo y confirma con `options.uploaded_file: true`.
                  Para referenciar un corte de un `doc_splitter` previo con `file_source: "item"` + `file_source_info`, usa [`PUT /verifications/{id}/add-items`](/api-reference/agregar-items-a-una-verificacion/agregar-items-a-una-verificación-existente) sobre una verificación existente: en `POST /verifications` no hay `doc_splitter` previo al que apuntar.
                properties:
                  file_url:
                    type: string
                    description: URL de un archivo presignado que se puede descargar para el ítem a verificar.
                    example: "https://www.somepresignedURL.com/downloadableFile"
                  file_password:
                    type: string
                    minLength: 1
                    maxLength: 128
                    writeOnly: true
                    description: |
                      Contraseña del PDF cuando el archivo de `file_url` está protegido. Trébol abre el documento con ella al recibirlo, procesa la copia sin contraseña y conserva el archivo original cifrado. Trébol almacena la contraseña cifrada en la base de datos y no la devuelve en respuestas ni webhooks. Si es incorrecta, el ítem termina con `item_error: invalid_file_password`. Se ignora para archivos que no son PDF. Aplica por ítem.
                    example: "clave-del-pdf"
                  people_scope:
                    type: array
                    description: Especifica el alcance de las personas que deben ser consideradas en la verificación.
                    items:
                      type: string
                      example: "powers"
                  client_item_type:
                    $ref: "#/components/schemas/ClientItemType"
                  allowed_item_types:
                    type: array
                    description: |
                      Solo para `doc_splitter`. Restringe los tipos que el splitter puede identificar. Acepta tipos built-in (por ejemplo `ac_mx`, `aa_mx`) y nombres de tipos de ítem personalizados (`cit_...`). Si se omite o está vacío, se usa el catálogo base completo.
                      **No confundir con** el `allowed_item_types` del `RequirementDefinition` (schema `AllowedItemType`): aquel es un enum cerrado usado en `record_validation_schema` para definir qué tipos satisfacen un requerimiento del expediente.
                    items:
                      type: string
                    example: ["ac_mx", "aa_mx"]
                  state_code:
                    type: string
                    description: >
                      Código numérico de la entidad federativa para filtrar un
                      ítem `siger` en la fase de `siger_documents` (valor
                      `documents`). Usa uno de los valores aceptados (1–32).
                    enum:
                      - "1"
                      - "2"
                      - "3"
                      - "4"
                      - "5"
                      - "6"
                      - "7"
                      - "8"
                      - "9"
                      - "10"
                      - "11"
                      - "12"
                      - "13"
                      - "14"
                      - "15"
                      - "16"
                      - "17"
                      - "18"
                      - "19"
                      - "20"
                      - "21"
                      - "22"
                      - "23"
                      - "24"
                      - "25"
                      - "26"
                      - "27"
                      - "28"
                      - "29"
                      - "30"
                      - "31"
                      - "32"
                    example: "9"
                  state_name:
                    type: string
                    description: >
                      Nombre de la entidad federativa para filtrar un ítem
                      `siger` en la fase de `siger_documents` (valor
                      `documents`). Debe coincidir con uno de los nombres
                      oficiales listados.
                    enum:
                      - "Aguascalientes"
                      - "Baja California"
                      - "Baja California Sur"
                      - "Campeche"
                      - "Coahuila de Zaragoza"
                      - "Colima"
                      - "Chiapas"
                      - "Chihuahua"
                      - "Ciudad de México"
                      - "Durango"
                      - "Guanajuato"
                      - "Guerrero"
                      - "Hidalgo"
                      - "Jalisco"
                      - "México"
                      - "Michoacán de Ocampo"
                      - "Morelos"
                      - "Nayarit"
                      - "Nuevo León"
                      - "Oaxaca"
                      - "Puebla"
                      - "Querétaro"
                      - "Quintana Roo"
                      - "San Luis Potosí"
                      - "Sinaloa"
                      - "Sonora"
                      - "Tabasco"
                      - "Tamaulipas"
                      - "Tlaxcala"
                      - "Veracruz de Ignacio de la Llave"
                      - "Yucatán"
                      - "Zacatecas"
                    example: "Ciudad de México"
                  fme:
                    type: string
                    description: >
                      Folio mercantil estatal para filtrar la búsqueda de la
                      empresa en la fase de `siger_documents` (valor
                      `documents`). Usa el folio tal como aparece en SIGER.
                    example: "FME-2024-001234"
                  legal_name:
                    type: string
                    description: >
                      Razón social para filtrar la búsqueda de la empresa en SIGER.
                      Debe coincidir con la denominación en SIGER.
                    example: "EMPRESA EJEMPLO, S.A. DE C.V."
        country:
          type: string
          description: El código del país en formato ISO 3166-1 alfa-2. Actualmente soportado solo para México ('mx').
        tag:
          type: string
          description: Una etiqueta única que identifica la verificación.
        tax_id:
          type: string
          description: El número de identificación fiscal de la empresa.
        email:
          type: string
          format: email
          description: Dirección de correo electrónico del cliente que solicita el onboarding.
          example: "jonh_doe@gmail.com"
        metadata:
          type: object
          description: Información adicional o metadatos asociados a la verificación.
          additionalProperties: true
        key_people:
          type: array
          description: Una lista de personas clave asociadas con la empresa que están sujetas a verificación.
          items:
            type: object
            properties:
              names:
                type: string
                description: El nombre completo de la persona clave.
              scope:
                type: array
                description: El alcance o las responsabilidades de la persona dentro de la empresa.
                items:
                  type: string
                  example: "powers"
        options:
          type: object
          description: Opciones adicionales para el ítem.
          properties:
            creator_email:
              type: string
              format: email
              description: Email del creador de la verificacion, el usuario empresarial.
            disable_siger:
              type: boolean
              description: Si el valor es true, el sersvicio de siger no se mostrará en la verificacion.
            siger_data_extraction:
              type: boolean
              description: |
                Si el valor es true, el sistema creará automáticamente items de tipo acta (ac_mx, aa_mx, fme_mx) solo para aquellos actos que contengan eventos relevantes de la empresa (cambios en administración, accionistas, capital social, etc.).
                El análisis FME se ejecuta para TODOS los actos independientemente del valor de este flag, almacenando los resultados en el item SIGER para consulta posterior. El flag solo controla si se crean los items de acta automáticamente.
            search_related_companies_siger:
              type: boolean
              description: Si el valor es true, se creará el item siger_shareholders que contiene información de las empresas relacionadas donde participan los accionistas de la compañía de la verificación. Útil para análisis de beneficiarios finales (UBOs) y estructuras corporativas relacionadas.
            require_files_for_generic_items:
              type: boolean
              description: Si el valor es true, los items de tipo generic que no tengan un file_url no se crearán.
              example: true
    AccountFlow:
      type: object
      properties:
        id:
          type: string
        account_id:
          type: string
        friendly_name:
          type: string
        id_slug:
          type: string
          description: Identificador único del flujo. Solo puede contener letras, números, guiones(-) y guiones bajos(_).
          example: "id-test-flow"
        flow_items:
          $ref: "#/components/schemas/VerificationTemplate"
        record_validation_schema:
          $ref: "#/components/schemas/RecordValidationSchema"
    AccountFlowStep:
      properties:
        id:
          type: string
          description: ID nombre del flujo.
          example: "ubos"
        url:
          type: string
          description: URL que apunta a la pagina correspondiente al paso del flujo. el mismo debe ser uno de los siguientes, de lo contrario se generara un error.
          enum:
            - "/(main-flow)/start/[accountId]/[flowId]"
            - "/(main-flow)/verification/[id]/docs-v2"
            - "/(main-flow)/verification/[id]/ubos"
            - "/(main-flow)/verification/[id]/forms"
            - "/(main-flow)/verification/[id]/check-out"
        text:
          type: string
          description: Texto que se mostrara en el paso del flujo.
          example: "Propietarios reales"
        isPrimary:
          type: boolean
          description: Indica si el paso es el principal del flujo.
        isLinkable:
          type: boolean
          description: Indica si el paso es direccionable a este paso especifico, si es true, el usuario se podra dirigir a este paso directamente desde su link.
        requestUboAddress:
          type: boolean
          description: Especificamente para el flujo de Ubos, si este valor es true, se le pedira al usuario un comprobante de domicilio para cada UBO.
    VerificationTemplate:
      type: object
      properties:
        id:
          type: string
          description: ID con el que se identifica el template de verificación.
        items:
          type: array
          description: Lista de items que conforman el template de verificación
          items:
            type: object
            required:
              - type
            properties:
              type:
                type: string
                description: Tipo de item de verificación
                example: "generic"
              options:
                type: object
                properties:
                  is_optional:
                    type: boolean
                    description: Indica si el item es opcional, si es true, el item no sera requerido para que finalice la verificacion.
                  ubos_threshold:
                    type: integer
                    description:
                      Indica el porcentaje mínimo que debe tener un accionista para tener que ser declarado en la sección de UBOs.
                      **Aplicara solo para items de tipo `ubos` y es opcional**.
                    example: 25
                  ubos_form_schema:
                    type: string
                    enum:
                      - "mx_form"
                      - "co_form"
                    description:
                      Especifica el esquema de formulario que se debe usar para la sección de UBOs.
                      Para más información sobre los esquemas de formulario, consulta la sección [Items del flujo](/guia-devs/crear-verificaciones/via-widget/items#forms).
                      **Aplicara solo para items de tipo `ubos` y es opcional**.
                    example: "mx_form"
                  ubos_schema_id:
                    type: string
                    description:
                      ID de un esquema de formulario personalizado creado con el endpoint de esquemas de formularios.
                      Cuando se especifica, el widget usa este esquema en lugar de los predeterminados (`mx_form` / `co_form`).
                      El esquema debe existir en la cuenta. Debe ser diferente a `mx_form` o `co_form`(Estos se especifican con `ubos_form_schema`).
                      **Aplicará solo para items de tipo `ubos` y es opcional**.
                    example: "ubos-custom-001"
                  schema_id:
                    type: string
                    description: |
                      ID del esquema de formulario. **Requerido para items de tipo `forms`**.
                      Debe corresponder a un esquema de formulario existente en la cuenta.
                    example: "some-test-form-schema"
                additionalProperties: true
        options:
          type: object
          description: Opciones adicionales para la verificacion.
          properties:
            creator_email:
              type: string
              format: email
              description: Email del creador de la verificacion, el usuario empresarial.
            next_steps_checkout:
              type: array
              description: Lista de pasos a seguir para tu prospecto al finalizar el flujo de onboarding. Se puede enviar un array vacío para no mostrar ningún paso.
              example:
                [
                  {
                    "title": "Documentos adicionales",
                    "description": "Es posible que se necesiten documentos adicionales para completar tu onboarding. En ese caso nos pondremos en contacto contigo.",
                  },
                  {
                    "title": "Firma del contrato",
                    "description": "Cuando se complete toda la información, un representante de ventas se pondrá en contacto contigo para firmar el contrato.",
                  },
                ]
              items:
                type: object
                properties:
                  title:
                    type: string
                    description: Titulo del paso.
                    example: "Documentos adicionales"
                  description:
                    type: string
                    description: Descripción del paso.
                    example: "Es posible que se necesiten documentos adicionales para completar tu onboarding. En ese caso nos pondremos en contacto contigo."
          additionalProperties: true
    AllowedItemType:
      type: string
      description: Los siguientes son items basados en documentos.
      enum:
        - "aa_mx"
        - "ac_mx"
        - "bank_statement"
        - "cc_co_ops"
        - "csf_mx"
        - "fme_mx"
        - "person_id"
        - "proof_address"
        - "pw_mx"
        - "property_deed"
        - "lien_certificate"
        - "property_tax_receipt"
        - "payroll_receipt"
        - "camara_comercio_co_extractor"
        - "trust_contract_fideicomiso_extractor"
        - "union_documents_extractor"
        - "designacion_responsable_cumplimiento_extractor"
        - "registro_actividades_vulnerables_extractor"
        - "irs_ein_assignment_letter_extractor"
        - "certificate_of_incumbency_extractor"
        - "certificate_of_incorporation_extractor"
        - "fincen_msb_registration_extractor"
        - "financial_statements_any"
        - "unkown(cuando el ítem no corresponde a ninguno)"
    RequirementDefinition:
      type: object
      properties:
        ui_options:
          type: object
          properties:
            label:
              type: string
              description: Etiqueta que se mostrará en la interfaz de usuario
              example: "Constancia de Situación Fiscal"
            description:
              type: string
              description: Descripción detallada del requerimiento
              example: "Documento que certifica que la empresa está al día con sus obligaciones fiscales."
            conditional_render:
              type: boolean
              description: Indica si el campo debe ser renderizado condicionalmente mediante un checkbox, que tiene como leyenda la propiedad conditional_render_label.
            conditional_render_label:
              type: string
              description: Etiqueta que se mostrará en la interfaz de usuario para el campo condicional.
              example: "¿Los poderes del representante legal figuran en un acta de asamblea o poder notarial?"
        allowed_item_types:
          type: array
          description: Lista de tipos de items permitidos para este requerimiento
          items:
            $ref: "#/components/schemas/AllowedItemType"
          example: ["csf_mx"]
        validation_options:
          type: object
          properties:
            on_invalid_type_error:
              type: string
              description: |
                Determina el comportamiento cuando el documento no pasa la validación de tipo o de ruleset.
                - `"invalidate"` (default): el widget muestra al prospecto una alerta de error. El prospecto puede subir otro documento o continuar con el actual. El requerimiento se marca como `status: "error"`.
                - `"ignore"`: el widget muestra al prospecto el requerimiento como "en revisión" sin error. El operador del dashboard resuelve manualmente desde la webapp con 3 opciones: invalidar y pedir nuevo documento, descartar sin acción, o aceptar y elegir el tipo de ítem para extracción.
                Esta configuración aplica por igual a errores de tipo de documento y a fallos de reglas del `ruleset`. Los errores de sistema (`validation_request_failed`) siempre se tratan como error independientemente de este valor.
                Consulta la [guía de Flujos de onboarding](/guia-devs/account-flows#comportamiento-ante-error-de-validación-validation_optionson_invalid_type_error) para más detalles.
              enum:
                - "invalidate"
                - "ignore"
            ruleset:
              type: array
              description: |
                Lista de reglas de validación de negocio que se evaluarán automáticamente sobre el documento mediante IA.
                Consulta la guía de [flujo de validación de documentos](/guia-devs/flujo-validacion-documentos#reglas-de-validación-predefinidas-de-trébol) de documentos para la documentación completa de reglas predefinidas (`vr_trebol_*`) y personalizadas.
                **Nota:** el campo `error_message` es requerido para este caso en particular.
              items:
                type: object
                required:
                  - id
                  - error_message
                properties:
                  id:
                    type: string
                    description: Identificador de la regla. Para reglas predefinidas de Trébol usa el prefijo `vr_trebol_`. Para reglas personalizadas, cualquier identificador único.
                    example: "vr_trebol_antiguedad"
                  error_message:
                    type: string
                    description: Mensaje de error personalizado que se mostrará al usuario cuando la regla no se cumpla. Requerido al configurar el ruleset en un account flow.
                    example: "La CSF debe tener menos de 60 días de antigüedad"
                  validation_rule:
                    type: string
                    description: Texto completo de la pregunta de validación para reglas personalizadas. No incluir en reglas predefinidas de Trébol (`vr_trebol_*`).
                    example: "¿El RFC visible en el documento coincide con el RFC registrado de la empresa?"
                  params:
                    type: object
                    description: Parámetros para sustituir placeholders en reglas predefinidas de Trébol.
                    additionalProperties:
                      oneOf:
                        - type: string
                        - type: number
                    example:
                      days: 60
        allowed_item_subtype:
          type: string
          description: El subtipo de item que se permite para este requerimiento, solo algunos items tienen subtipos, como los csf, o los bank statements.
          enum:
            - "business"
            - "individual"
          example: "business"
        required_options:
          type: object
          properties:
            people_scope:
              type: array
              items:
                type: string
                description: El alcance de las personas que deben ser consideradas en la verificación, aplica cuando el tipo de item es un person_id.
                enum:
                  - "powers"
      required:
        - ui_options
        - allowed_item_types
    RecordValidationSchema:
      type: object
      description: Schema de validación para el expediente de la verificacion. Las reglas que se definan aqui sera la que determine la finalizacion de la verificacion.
      properties:
        version:
          type: number
          description: Version del schema de validacion, ahora solo soporta la version 2.
          enum:
            - 2
        requirements:
          type: object
          description: Mapa de requerimientos donde la clave es un ID personalizado (por ejemplo, "doc_1")
          additionalProperties:
            $ref: "#/components/schemas/RequirementDefinition"
          example:
            doc_1:
              ui_options:
                label: "Constancia de Situación Fiscal"
                description: "Documento que certifica que la empresa está al día con sus obligaciones fiscales."
                conditional_render: true
                conditional_render_label: "¿Los poderes del representante legal figuran en un acta de asamblea o poder notarial?"
              allowed_item_types:
                - "csf_mx"
              validation_options:
                on_invalid_type_error: "invalidate"
        optional_requirements:
          type: object
          description: Mapa de requerimientos opcionales donde la clave es un ID personalizado (por ejemplo, "doc_1")
          additionalProperties:
            $ref: "#/components/schemas/RequirementDefinition"
    VerificationItemValidationSchema:
      type: object
      description: Schema de validación para items individuales
      properties:
        validationsMap:
          type: object
          description: Mapa de validaciones por tipo de item o validación específica
          additionalProperties:
            type: object
            properties:
              validationExpression:
                type: string
                description: Expresión que debe evaluarse como verdadera para que la validación pase
                example: "businessName && businessTaxId"
              trigger:
                type: string
                description: Evento que dispara la validación
                enum:
                  ["verification_item.classified", "verification_item.complete"]
              onValidationFailure:
                type: object
                description: Acciones a tomar cuando la validación falla
                properties:
                  actionType:
                    type: string
                    enum: ["invalidate", "warn"]
                    description: Tipo de acción a tomar
                  message:
                    type: string
                    description: Mensaje de error o advertencia
              onValidationSuccess:
                type: object
                description: Acciones a tomar cuando la validación es exitosa
                properties:
                  actionType:
                    type: string
                    enum: ["invalidate", "warn"]
                    description: Tipo de acción a tomar
                  message:
                    type: string
                    description: Mensaje de éxito
            required:
              - validationExpression
              - trigger
              - onValidationFailure
    AccountFlowCreate:
      type: object
      required:
        - friendly_name
        - id_slug
      properties:
        friendly_name:
          type: string
        id_slug:
          type: string
          description: Identificador único del flujo. Solo puede contener letras, números, guiones(-) y guiones bajos(_).
          example: "id-test-flow"
        flow_items:
          $ref: "#/components/schemas/VerificationTemplate"
        record_validation_schema:
          $ref: "#/components/schemas/RecordValidationSchema"
    AccountFlowUpdate:
      type: object
      properties:
        friendly_name:
          type: string
        id_slug:
          type: string
          description: Identificador único del flujo. Solo puede contener letras, números, guiones(-) y guiones bajos(_).
          example: "id-test-flow"
        flow_items:
          $ref: "#/components/schemas/VerificationTemplate"
        record_validation_schema:
          $ref: "#/components/schemas/RecordValidationSchema"
    ApiKeyInfo:
      type: object
      description: Información básica de una API key (sin mostrar la clave por seguridad)
      properties:
        id:
          type: string
          description: ID único de la API key
          example: "ak_1234567890abcdef"
        created_at:
          type: string
          format: date-time
          description: Fecha y hora de creación de la API key
          example: "2024-01-15T10:30:00Z"
      required:
        - id
        - created_at

    RetentionPolicy:
      type: object
      description: Política de retención de datos de la cuenta
      properties:
        retention_days:
          type: integer
          minimum: 1
          maximum: 3650
          description: Número de días que se conservarán los datos antes de ser eliminados automáticamente
          example: 30
      required:
        - retention_days

    RetentionPolicyRequest:
      type: object
      description: Solicitud para crear o actualizar la política de retención
      properties:
        retention_days:
          type: integer
          minimum: 1
          maximum: 3650
          description: Número de días que se conservarán los datos antes de ser eliminados automáticamente
          example: 30
      required:
        - retention_days

    PublicFormSchema:
      type: object
      description: Esquema de formulario público para la cuenta
      properties:
        id_schema:
          type: string
          description: Identificador único del esquema
          example: "onboarding-form"
        account_id:
          type: string
          description: ID de la cuenta a la que pertenece el esquema
          example: "acc_1234567890abcdef"
        name:
          type: string
          description: Nombre del esquema de formulario
          example: "Formulario de Onboarding"
        ui_schema_definition:
          $ref: "#/components/schemas/UISchemaField"
      required:
        - id_schema
        - account_id
        - name
        - ui_schema_definition

    UISchemaField:
      type: object
      description: |
        Definición de campo de esquema de interfaz de usuario. Esta estructura permite definir formularios 
        dinámicos con campos anidados y diferentes tipos de entrada. El esquema soporta campos simples 
        como texto, números, fechas, y campos complejos como secciones que pueden contener otros campos.

        **Estructura jerárquica**: Los campos pueden anidarse usando el tipo "section", permitiendo 
        crear formularios con múltiples niveles de organización.

        **Validación automática**: El sistema valida automáticamente que todos los campos referenciados 
        en ui_order existan como propiedades en el mismo nivel.
      properties:
        ui_order:
          type: array
          items:
            type: string
          description: |
            Array que define el orden de aparición de los campos en la interfaz de usuario. 
            Debe contener los nombres de todos los campos definidos en el mismo nivel del objeto.
            Es obligatorio en el nivel raíz y opcional en secciones anidadas o en tablas para configurar el orden de sus columnas.
          example: ["nombre", "apellido", "notaria"]
        ui_type:
          type: string
          enum:
            [
              "file",
              "date",
              "section",
              "select",
              "multiselect",
              "number",
              "email",
              "password",
              "text",
              "table",
              "checkbox",
              "country",
            ]
          description: |
            Tipo de campo que determina cómo se renderiza en la interfaz:
            - **text**: Campo de texto simple
            - **number**: Campo numérico
            - **email**: Campo de email con validación
            - **password**: Campo de contraseña (oculto)
            - **date**: Selector de fecha
            - **file**: Selector de archivo
            - **select**: Lista desplegable (requiere ui_items)
            - **multiselect**: Selección múltiple (requiere ui_items)
            - **section**: Contenedor para agrupar otros campos
            - **table**: Tabla para solicitar un número indeterminado de datos de cualquier tipo de campo **Excepto para el tipo de campo `file`**. Requiere ui_columns.
            - **paragraph**: Label o texto que no tiene ningún input asociado, usado a nivel informativo. Requiere solamente ui_label.
            - **heading**: Encabezado que no tiene ningún input asociado, usado a nivel informativo. Requiere solamente ui_label.
            - **checkbox**: Campo booleano (true/false) renderizado como checkbox con label. Útil para preguntas de sí/no.
            - **country**: Selector de país con búsqueda. Almacena el nombre del país en la llave del campo y genera automáticamente una llave adicional con sufijo `_code` que contiene el código ISO 3166-1 alpha-2 (ej. si la llave es `nationality`, se almacena `nationality: "México"` y `nationality_code: "MX"`).
          example: "text"
        ui_label:
          type: string
          description: |
            Etiqueta visible que se muestra al usuario para identificar el campo. 
            Debe ser descriptivo y claro para facilitar la comprensión del usuario.
          example: "Nombre"
        ui_required:
          type: boolean
          description: |
            Indica si el campo es obligatorio. Los campos requeridos deben ser 
            completados antes de poder enviar el formulario.
          example: true
        ui_items:
          type: array
          items:
            oneOf:
              - type: string
              - type: object
                properties:
                  label:
                    type: string
                    description: Texto visible para el usuario.
                  value:
                    type: string
                    description: Valor almacenado internamente.
                required:
                  - label
                  - value
          description: |
            Array de opciones disponibles para campos de tipo select y multiselect.
            Soporta dos formatos:
            - **Strings**: el valor almacenado es igual al texto visible (ej. `["Opción A", "Opción B"]`).
            - **Objetos `{ label, value }`**: muestra `label` al usuario y almacena `value` (ej. `[{ "label": "Persona", "value": "person" }]`).
            Si se usa el formato de objetos con `depends_on_value`, los valores deben coincidir con `value`, no con `label`.
          example: ["opcion1", "opcion2", "opcion3"]
        ui_columns:
          type: object
          description: |
            Objeto que define las columnas de la tabla.
            Cada propiedad del objeto es una columna y debe tener un objeto con las propiedades:
            - ui_type: Tipo de campo
            - ui_label: Etiqueta de la columna
            - ui_required: Indica si la columna es obligatoria.
            - ui_items: Array de opciones disponibles para campos de tipo select, multiselect.
          example:
            nombre:
              ui_type: "text"
              ui_label: "Nombre"
              ui_required: true
            tipo_id:
              ui_type: "select"
              ui_label: "Tipo ID"
              ui_required: true
              ui_items: ["RFC", "CURP"]
      additionalProperties:
        oneOf:
          - $ref: "#/components/schemas/UISchemaField"
          - type: "array"
            items:
              type: string
          - type: string
          - type: boolean
      example:
        ui_order: ["junta_directiva", "nombre", "apellido", "notaria"]
        nombre:
          ui_type: "text"
          ui_label: "Nombre"
        apellido:
          ui_type: "text"
          ui_label: "Apellido"
        junta_directiva:
          ui_type: "table"
          ui_label: "Integrantes miembros de la junta directiva"
          ui_columns:
            id_type:
              ui_type: "select"
              ui_label: "ID"
              ui_items: ["RFC", "CURP"]
            id_number:
              ui_type: "text"
              ui_label: "No. de identificación"
            names:
              ui_type: "text"
              ui_label: "Nombres y Apellidos"
        notaria:
          ui_type: "section"
          ui_label: "Notaria"
          ui_order: ["nombre", "direccion", "identidad"]
          nombre:
            ui_type: "text"
            ui_label: "Nombre"
          direccion:
            ui_type: "text"
            ui_label: "Direccion"
          identidad:
            ui_type: "section"
            ui_label: "Identidad"
            ui_order: ["curp", "rfc"]
            curp:
              ui_type: "text"
              ui_label: "CURP"
            rfc:
              ui_type: "text"
              ui_label: "RFC"
    Webhook:
      type: object
      properties:
        id:
          type: string
          description: ID único del webhook
          example: "wh_123"
        url:
          type: string
          format: uri
          description: URL a la que Trebol enviará las notificaciones
          example: "https://example.com/webhooks/trebol"
        events:
          type: array
          description: Lista de eventos suscritos
          items:
            type: string
            example: "verification.v2.created"
        status:
          type: string
          enum: ["enabled", "disabled"]
          description: Indica si el webhook está habilitado o deshabilitado. Al crear el webhook, el status por defecto es "enabled".
          example: "enabled"
        description:
          type: string
          nullable: true
          description: Descripción opcional del webhook
        secret:
          type: string
          description: Secreto del webhook. Se asigna una vez que se crea el webhook y solo se muestra una vez.
          example: "whsec_XXXXXXXXXXXXXXXXXXXXXXXX"
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    WebhookGet:
      type: object
      properties:
        id:
          type: string
          description: ID único del webhook
          example: "wh_123"
        url:
          type: string
          format: uri
          description: URL a la que Trebol enviará las notificaciones
          example: "https://example.com/webhooks/trebol"
        events:
          type: array
          description: Lista de eventos suscritos
          items:
            type: string
            example: "verification.v2.created"
        status:
          type: string
          enum: ["enabled", "disabled"]
          description: Indica si el webhook está habilitado o deshabilitado
          example: "enabled"
        description:
          type: string
          nullable: true
          description: Descripción opcional del webhook
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    WebhookCreate:
      type: object
      required:
        - url
        - events
      properties:
        url:
          type: string
          format: uri
          description: URL a la que Trebol enviará las notificaciones
          example: "https://example.com/webhooks/trebol"
        events:
          type: array
          description: Lista de eventos a suscribir
          example: ["verification.v2.created"]
          items:
            type: string
        description:
          type: string
          nullable: true
          example: "Webhook principal de producción"
    WebhookUpdate:
      type: object
      properties:
        url:
          type: string
          format: uri
          description: URL a la que Trebol enviará las notificaciones
          example: "https://example.com/webhooks/trebol"
        events:
          type: array
          description: Lista de eventos a suscribir
          example: ["verification.v2.created"]
          items:
            type: string
        description:
          type: string
          nullable: true
          example: "Webhook principal de producción"
        status:
          type: string
          enum: ["enabled", "disabled"]
          example: "enabled"
    ExportWithKeyPeopleRequest:
      type: object
      required:
        - key_people
      properties:
        key_people:
          type: array
          description: Array de objetos que mapean variables de apoderados en la plantilla con personas y roles específicos.
          items:
            type: object
            required:
              - key
              - person_id
              - role_id
            properties:
              key:
                type: string
                description: Clave que identifica la variable en la plantilla. Debe coincidir con la nomenclatura {key_person_#} donde # es un número (ej: "key_person_1", "key_person_2").
                example: "key_person_1"
              person_id:
                type: number
                description: ID de la persona. Se obtiene del campo `people_id` en el array `key_people` del endpoint `/v2/verifications/{id}/people`.
                example: 10
              role_id:
                type: string
                description: ID del rol. Se obtiene del campo `id` en los roles dentro del array `key_people` del endpoint `/v2/verifications/{id}/people`.
                example: "role_123"
    CreateCustomItemTypeRequest:
      type: object
      required:
        - name
        - user_input
        - friendly_name
      properties:
        name:
          type: string
          description: "Clave del tipo de documento. Debe empezar con `cit_` y no puede contener espacios (ej. `cit_contrato_arrendamiento`). Única por cuenta."
          example: "cit_contrato_arrendamiento"
        user_input:
          type: string
          description: Instrucciones para identificar este tipo de documento.
          example: "Este documento es un contrato de arrendamiento inmobiliario firmado ante notario."
        friendly_name:
          type: string
          description: Nombre legible para interfaces. Entre 2 y 255 caracteres.
          example: "Contrato de arrendamiento"
        auto_improve:
          type: boolean
          default: true
          description: Cuando es `false`, Trébol no ejecuta mejora automática y conserva las instrucciones tal cual.
    UpdateCustomItemTypeRequest:
      type: object
      description: Debes enviar al menos un campo (`name`, `friendly_name` o `status`).
      properties:
        name:
          type: string
          description: Renombra el tipo. No puede contener espacios. Única por cuenta.
        friendly_name:
          type: string
          description: Actualiza el nombre legible. Entre 2 y 255 caracteres.
        status:
          type: string
          enum: ["active", "archived"]
          description: "`archived`: pausa el tipo, sigue en el listado y puede reactivarse. `active`: reactiva un tipo archivado."
    CustomItemTypeProcess:
      type: object
      properties:
        id:
          type: string
          description: Identificador único del proceso generado por Trébol.
          example: "ccp_def456"
        process_reference:
          type: string
          description: |
            Etiqueta del proceso asignada por el usuario. Identifica el resultado de este proceso en el ítem procesado: cada paso de `item_value.pipeline` lo trae en `process_reference`. Ver [Tipos de ítem personalizados](/producto/guias/tipos-de-item-personalizados#donde-salen-los-resultados).
          example: "extraer_montos"
        process_type:
          type: string
          enum: ["classification", "validation", "extraction"]
          description: Tipo de proceso.
        is_active:
          type: boolean
          description: Indica si el proceso está activo.
          example: true
        failure_policy:
          type: string
          nullable: true
          enum: ["warning", "hard_stop", null]
          description: "Política de fallo para validaciones. `warning`: el ítem se pausa hasta que se revise el resultado. `hard_stop`: si la regla no se cumple, el ítem se da por finalizado. `null`: el ítem continúa procesándose aunque la regla falle. Para clasificación y extracción siempre es `null`."
        active_version_id:
          type: integer
          nullable: true
          description: ID de la versión activa del proceso.
          example: 42
        version_number:
          type: integer
          description: Número secuencial de la versión activa.
          example: 1
        created_at:
          type: string
          format: date-time
          description: Fecha de creación del proceso.
        updated_at:
          type: string
          format: date-time
          description: Fecha de última actualización del proceso.
    CustomItemTypeProcessWithContent:
      allOf:
        - $ref: "#/components/schemas/CustomItemTypeProcess"
        - type: object
          properties:
            user_input:
              type: string
              description: Instrucciones escritas por el usuario para este proceso.
              example: "Este documento es un contrato de arrendamiento..."
            json_schema:
              type: object
              nullable: true
              description: Esquema JSON de salida para procesos de extracción. NULL para clasificación y validación.
    CustomItemTypeData:
      type: object
      properties:
        id:
          type: string
          description: Identificador único del tipo generado por Trébol.
          example: "cit_abc123"
        name:
          type: string
          description: Clave del tipo de documento (empieza con `cit_`).
          example: "cit_contrato_arrendamiento"
        friendly_name:
          type: string
          description: Nombre legible para interfaces.
          example: "Contrato de arrendamiento"
        status:
          type: string
          enum: ["active", "archived"]
          description: Estado del tipo.
          example: "active"
        is_global:
          type: boolean
          readOnly: true
          description: Indica si Trébol comparte este tipo con todas las cuentas. Los tipos globales y sus procesos son de solo lectura.
          example: false
        created_at:
          type: string
          format: date-time
          description: Fecha de creación.
        updated_at:
          type: string
          format: date-time
          description: Fecha de última actualización.
        processes:
          type: array
          description: Procesos vinculados al tipo.
          items:
            $ref: "#/components/schemas/CustomItemTypeProcess"
    CustomItemTypeReadData:
      description: Tipo de ítem personalizado con procesos completos (incluye user_input y json_schema). Usado en respuestas GET.
      allOf:
        - $ref: "#/components/schemas/CustomItemTypeData"
        - type: object
          properties:
            processes:
              type: array
              description: Procesos vinculados al tipo con contenido completo (user_input, json_schema).
              items:
                $ref: "#/components/schemas/CustomItemTypeProcessWithContent"
    CustomItemTypeResponse:
      type: object
      properties:
        success:
          type: boolean
          example: true
        data:
          $ref: "#/components/schemas/CustomItemTypeData"
    CustomItemTypeUpdateResponse:
      type: object
      properties:
        success:
          type: boolean
          example: true
        data:
          type: object
          description: Tipo actualizado (sin procesos).
          properties:
            id:
              type: string
              example: "cit_abc123"
            name:
              type: string
              example: "cit_contrato_arrendamiento_v2"
            friendly_name:
              type: string
            status:
              type: string
              enum: ["active", "archived"]
            is_global:
              type: boolean
              readOnly: true
              description: Indica si Trébol comparte este tipo con todas las cuentas. Los tipos globales y sus procesos son de solo lectura.
              example: false
            created_at:
              type: string
              format: date-time
            updated_at:
              type: string
              format: date-time
    CustomItemTypeReadResponse:
      type: object
      properties:
        success:
          type: boolean
          example: true
        data:
          $ref: "#/components/schemas/CustomItemTypeReadData"
    CustomItemTypeReadListResponse:
      type: object
      properties:
        success:
          type: boolean
          example: true
        data:
          type: array
          items:
            $ref: "#/components/schemas/CustomItemTypeReadData"
        next:
          type: string
          nullable: true
          description: Token de cursor para la siguiente página. `null` o ausente si no hay más resultados.
    CustomItemTypeProcessResponse:
      type: object
      properties:
        success:
          type: boolean
          example: true
        data:
          $ref: "#/components/schemas/CustomItemTypeProcess"
    CustomItemTypeProcessDetailResponse:
      type: object
      properties:
        success:
          type: boolean
          example: true
        data:
          $ref: "#/components/schemas/CustomItemTypeProcessWithContent"
    CreateCustomItemTypeProcessRequest:
      type: object
      required:
        - process_type
        - process_reference
        - user_input
      properties:
        process_type:
          type: string
          enum: ["validation", "extraction"]
          description: "Tipo de proceso a crear. Hasta 5 procesos de extracción y 20 de validación por tipo."
        process_reference:
          type: string
          description: Etiqueta del proceso. Única dentro del mismo tipo.
          example: "extraer_montos"
        user_input:
          type: string
          description: Instrucciones escritas por el usuario para este proceso.
          example: "Extrae todos los montos monetarios del contrato."
        json_schema:
          type: object
          description: 'Solo para procesos de extracción. Define el esquema JSON de salida. Cuando se envía, `auto_improve` se establece en `false` automáticamente; enviar `auto_improve: true` junto con `json_schema` devuelve error 400. La raíz debe ser `type: object` con `properties`. Usa `type: ["<tipo>", "null"]` para campos anulables. Consulta la [estructura del json_schema](/producto/guias/tipos-de-item-personalizados#estructura-del-json_schema) para el formato requerido y ejemplos.'
        auto_improve:
          type: boolean
          default: true
          description: "Para extracción sin `json_schema`, debe enviarse como `true` (o se omite; por defecto `true`). Enviar `false` sin `json_schema` devuelve error 400. Cuando se envía `json_schema`, `auto_improve` se establece en `false` automáticamente; enviar `true` devuelve error 400. Para validación, es opcional (por defecto `true`)."
        failure_policy:
          type: string
          nullable: true
          enum: ["warning", "hard_stop", null]
          description: "Solo para validación. `warning`: el ítem se pausa hasta que se revise el resultado. `hard_stop`: si la regla no se cumple, el ítem se da por finalizado. `null`: el ítem continúa procesándose aunque la regla falle. Se rechaza si se envía en otro tipo de proceso."
    UpdateCustomItemTypeProcessRequest:
      type: object
      description: Debes enviar al menos un campo. `process_type` y `id` no se pueden cambiar.
      properties:
        process_reference:
          type: string
          description: Renombra la etiqueta. Única dentro del mismo tipo.
        is_active:
          type: boolean
          description: Activa o pausa el proceso sin eliminarlo. El proceso de clasificación no se puede pausar.
        user_input:
          type: string
          description: Nuevas instrucciones. Al cambiarlas se crea una nueva versión del proceso, que pasa a ser la activa.
        json_schema:
          type: object
          description: "Solo para procesos de extracción. Define el esquema JSON de salida. Enviarlo crea una nueva versión del proceso. Cuando se envía, `auto_improve` se establece en `false` automáticamente; enviar `auto_improve: true` junto con `json_schema` devuelve error 400. Enviarlo en un proceso que no es de extracción devuelve 400. Consulta la [estructura del json_schema](/producto/guias/tipos-de-item-personalizados#estructura-del-json_schema) para el formato requerido y ejemplos."
        auto_improve:
          type: boolean
          default: true
          description: "Solo aplica cuando `user_input` cambia. Si es `false`, las instrucciones mejoradas se rellenan con el `user_input` tal cual. Cuando se envía `json_schema`, `auto_improve` se establece en `false` automáticamente; enviar `true` devuelve error 400."
        failure_policy:
          type: string
          nullable: true
          enum: ["warning", "hard_stop", null]
          description: "Solo para validación. `warning`: el ítem se pausa hasta que se revise el resultado. `hard_stop`: si la regla no se cumple, el ítem se da por finalizado. `null`: el ítem continúa procesándose aunque la regla falle."
