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

# Actualizar parcialmente lead

> Actualiza campos editables del lead, etapa del pipeline, overrides de atribución y snapshots de contacto.

**Scopes requeridos:** `leads.write`


## OpenAPI

````yaml /es/api-reference/openapi.yaml patch /api/v1/leads/{lead_id}
openapi: 3.1.0
info:
  title: RoofKit Partner API
  version: 1.0.0
  summary: API REST JSON para integraciones externas de socios de RoofKit.
  contact:
    name: RoofKit Engineering
  description: >-
    RoofKit Partner API v1 autentica solicitudes con API keys del workspace. Las
    API keys vinculan cada solicitud exactamente a un workspace; las rutas de
    Partner API no aceptan roofer_id, workspace_id ni identificadores de tenant.
    Los endpoints autenticados están limitados a 60 solicitudes por minuto por
    API key, método y plantilla de ruta; los intentos de autenticación inválidos
    se limitan por separado a 20 solicitudes por minuto por cliente y endpoint.
    Los parámetros y campos de fecha/hora aceptan ISO 8601 con Z o un desfase
    ±HH:MM, por ejemplo 2026-09-07T04:00:00Z o 2026-09-07T00:00:00-04:00. Ambos
    indican el mismo instante y devuelven el mismo resultado. Codifica + como
    %2B en una query string. Las respuestas usan UTC.


    Una fecha/hora sin desfase, por ejemplo 2026-09-07T04:00:00, está obsoleta.
    Hasta la fecha de retiro, 2027-01-10T00:00:00Z, se interpreta como UTC, y la
    respuesta incluye un header `Deprecation` (RFC 9745) y un header `Sunset`
    (RFC 8594). A partir de la fecha de retiro, se requiere Z o un desfase
    ±HH:MM. Desde entonces, una fecha/hora sin desfase devuelve 400 con el
    código `VALIDATION_ERROR`, y la respuesta no incluye ningún header
    `Deprecation` ni `Sunset`.


    Cada API key tiene solo los scopes que un propietario o administrador del
    workspace eligió al crear la key, y sus scopes nunca cambian. Cada operación
    indica los scopes que requiere en `x-required-scopes`. Una key nueva en
    Configuración empieza con el nivel predefinido Solo lectura: `leads.read`,
    `analytics.read`, `reports.read` y `data_objects.read`. Una key de Solo
    lectura puede llamar a todas las operaciones de lectura excepto las
    exportaciones, las lecturas de Sales Visualizer y los Data Objects en
    papelera, y no puede llamar a ninguna operación de escritura. Una llamada
    que necesita un scope que la key no tiene devuelve 403 `FORBIDDEN`, y
    `error.details.required_scope` indica un scope faltante.
servers:
  - url: https://api.roofkit.ai
    description: Origen canónico de RoofKit Partner API
security:
  - ApiKeyBearer: []
tags:
  - name: Foundation
    description: Endpoints base de autenticación y contrato.
  - name: Leads
    description: Endpoints de sincronización de leads para CRM de socios.
  - name: Attribution
    description: >-
      Endpoints de atribución de marketing, analíticas de campañas e ingesta de
      eventos para socios.
  - name: Pipeline
    description: Metadatos del pipeline de leads legibles para socios.
  - name: Reports
    description: >-
      Endpoints para importar, listar, obtener, exportar y descargar reportes de
      socios.
  - name: Visualizer
    description: >-
      Endpoints de Partner para crear Sales Visualizer, generar visualizaciones,
      crear enlaces alojados de subida de fotos, leer imágenes, consultar el
      historial de sesión y crear enlaces compartidos.
  - name: Estimates
    description: >-
      Creación y lectura de Budget Estimates de Partner para el workspace
      vinculado a la key.
  - name: Objects
    description: >-
      Endpoints de Partner para descubrimiento, esquema, registros, relaciones,
      vistas y administración de Data Objects.
paths:
  /api/v1/leads/{lead_id}:
    patch:
      tags:
        - Leads
      summary: Actualizar parcialmente lead
      description: >-
        Actualiza campos editables del lead, etapa del pipeline, overrides de
        atribución y snapshots de contacto.
      operationId: Patch lead
      parameters:
        - $ref: '#/components/parameters/LeadId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LeadPatch'
      responses:
        '200':
          description: Lead actualizado.
          headers:
            Idempotency-Replayed:
              $ref: '#/components/headers/IdempotencyReplayed'
            Deprecation:
              $ref: '#/components/headers/Deprecation'
            Sunset:
              $ref: '#/components/headers/Sunset'
          content:
            application/json:
              schema:
                type: object
                additionalProperties: false
                required:
                  - lead
                  - updated
                properties:
                  lead:
                    $ref: '#/components/schemas/Lead'
                  updated:
                    type: boolean
        '400':
          $ref: '#/components/responses/ValidationError'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
components:
  parameters:
    LeadId:
      name: lead_id
      in: path
      required: true
      schema:
        type: string
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: true
      description: >-
        Un valor único para cada solicitud nueva, como un UUID. Envíe el mismo
        valor para reintentar una solicitud de forma segura. La misma clave y el
        mismo payload repiten la primera respuesta con `Idempotency-Replayed:
        true`.
      schema:
        type: string
        minLength: 1
        maxLength: 160
  schemas:
    LeadPatch:
      type: object
      additionalProperties: false
      properties:
        contact_name:
          type:
            - string
            - 'null'
          maxLength: 200
        contact_email:
          type:
            - string
            - 'null'
          format: email
        contact_phone:
          description: >-
            Teléfono solo de EE. UU. Valores inválidos o no estadounidenses
            devuelven VALIDATION_ERROR.
          type:
            - string
            - 'null'
        property_address:
          description: >-
            Dirección de propiedad opcional. Se aceptan vacío, país EE. UU.
            explícito o formatos de estado + ZIP de EE. UU.; valores claramente
            no estadounidenses devuelven VALIDATION_ERROR.
          type:
            - string
            - 'null'
          maxLength: 500
        form_data:
          $ref: '#/components/schemas/LeadCustomFieldsWrite'
        custom_fields:
          $ref: '#/components/schemas/LeadCustomFieldsWrite'
        selected_material_id:
          type:
            - string
            - 'null'
        selected_color_id:
          type:
            - string
            - 'null'
        selected_shape_id:
          type:
            - string
            - 'null'
        status_stage_id:
          type: string
        attribution:
          $ref: '#/components/schemas/Attribution'
        marketing_attribution_overrides:
          $ref: '#/components/schemas/AttributionOverrides'
        notes:
          type:
            - string
            - 'null'
          maxLength: 5000
        quote_value:
          $ref: '#/components/schemas/LeadMoneyInput'
        sales_value:
          $ref: '#/components/schemas/LeadMoneyInput'
        follow_up_date:
          type:
            - string
            - 'null'
          format: date-time
          description: Fecha/hora ISO 8601 con Z o un desfase ±HH:MM. Se almacena en UTC.
        lead_type:
          description: >-
            Clave o etiqueta actual de un tipo de lead del workspace. RoofKit
            guarda la clave. Si se omite, se conserva el valor actual, incluso
            si está vacío. Un valor enviado reemplaza el actual. Un valor
            desconocido devuelve VALIDATION_ERROR.
          type: string
          minLength: 1
          maxLength: 100
    Lead:
      type: object
      additionalProperties: false
      required:
        - id
        - contact_name
        - contact_email
        - contact_phone
        - property_address
        - status
        - status_stage_id
        - attribution
        - communication_summary
        - created_at
        - updated_at
      properties:
        id:
          type: string
        external_id:
          type:
            - string
            - 'null'
        external_source:
          type:
            - string
            - 'null'
        contact_name:
          type:
            - string
            - 'null'
        contact_email:
          type:
            - string
            - 'null'
          format: email
        contact_phone:
          description: Dígitos telefónicos almacenados para el lead.
          type:
            - string
            - 'null'
        property_address:
          description: Texto de dirección de la propiedad del lead.
          type:
            - string
            - 'null'
        status:
          description: >-
            Grupo de compatibilidad del estado de Contacts (not_set, pending,
            appointment_scheduled, sold o lost). Un workspace que importa su CRM
            guarda la etapa del negocio en Opportunities, y sus leads pueden
            quedar en not_set.
          type: string
        status_stage_id:
          description: Id del estado de Contacts.
          type:
            - string
            - 'null'
        status_label:
          description: Etiqueta del estado de Contacts.
          type:
            - string
            - 'null'
        status_sort_order:
          type:
            - integer
            - 'null'
        is_conversion_stage:
          type: boolean
        stage_timestamps:
          type:
            - object
            - 'null'
          additionalProperties:
            type:
              - string
              - 'null'
        funnel_gap_summary:
          type:
            - object
            - 'null'
          additionalProperties: true
        attribution:
          $ref: '#/components/schemas/Attribution'
        lead_type:
          description: >-
            Clave del tipo de lead. Indica cómo llegó el contacto. Null cuando
            no está definida.
          type:
            - string
            - 'null'
        lead_type_label:
          description: >-
            Etiqueta actual de lead_type en el workspace. Null cuando lead_type
            es null.
          type:
            - string
            - 'null'
        landing_url:
          description: Primera página en la que el contacto convirtió, sin la query string.
          type:
            - string
            - 'null'
        first_form_name:
          description: Nombre del primer formulario que envió el contacto.
          type:
            - string
            - 'null'
        communication_summary:
          $ref: '#/components/schemas/LeadCommunicationSummary'
        form_data:
          $ref: '#/components/schemas/JsonRecord'
        custom_fields:
          $ref: '#/components/schemas/JsonRecord'
        selected_material_id:
          type:
            - string
            - 'null'
        selected_color_id:
          type:
            - string
            - 'null'
        selected_shape_id:
          type:
            - string
            - 'null'
        notes:
          type:
            - string
            - 'null'
        quote_value:
          type:
            - number
            - 'null'
        sales_value:
          type:
            - number
            - 'null'
        follow_up_date:
          type:
            - string
            - 'null'
          format: date-time
        converted_at:
          type:
            - string
            - 'null'
          format: date-time
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    LeadCustomFieldsWrite:
      type: object
      additionalProperties:
        oneOf:
          - type: string
          - type: number
          - type: boolean
          - type: 'null'
          - type: array
            items:
              type: string
    Attribution:
      type: object
      additionalProperties: false
      properties:
        source:
          type:
            - string
            - 'null'
        medium:
          type:
            - string
            - 'null'
        campaign:
          type:
            - string
            - 'null'
        content:
          type:
            - string
            - 'null'
        conversion_url:
          type:
            - string
            - 'null'
          format: uri
        entry:
          description: >-
            Entrada al sitio web de este punto de contacto. Se omite cuando no
            está definida. No reemplaza source.
          type: string
          enum:
            - button
            - embed
            - direct
    AttributionOverrides:
      type: object
      additionalProperties: false
      properties:
        source:
          type:
            - string
            - 'null'
        medium:
          type:
            - string
            - 'null'
        campaign:
          type:
            - string
            - 'null'
        content:
          type:
            - string
            - 'null'
    LeadMoneyInput:
      description: >-
        Se acepta un número o una cadena numérica al escribir. Las respuestas
        serializadas usan número o null.
      oneOf:
        - type: number
          minimum: 0
          maximum: 10000000
        - type: string
          pattern: ^[0-9]+(\.[0-9]+)?$
        - type: 'null'
    LeadCommunicationSummary:
      type: object
      additionalProperties: false
      required:
        - last_call_at
        - last_sms_at
        - call_count
        - answered_call_count
        - missed_call_count
        - sms_inbound_count
        - sms_outbound_count
        - last_tracking_number
        - last_communication_source
        - last_communication_campaign
      properties:
        last_call_at:
          type:
            - string
            - 'null'
          format: date-time
        last_sms_at:
          type:
            - string
            - 'null'
          format: date-time
        call_count:
          type: integer
        answered_call_count:
          type: integer
        missed_call_count:
          type: integer
        sms_inbound_count:
          type: integer
        sms_outbound_count:
          type: integer
        last_tracking_number:
          oneOf:
            - $ref: '#/components/schemas/TrackingNumberSummary'
            - type: 'null'
        last_communication_source:
          type:
            - string
            - 'null'
        last_communication_campaign:
          type:
            - string
            - 'null'
    JsonRecord:
      type: object
      additionalProperties:
        oneOf:
          - type: string
          - type: number
          - type: boolean
          - type: 'null'
          - type: array
            items:
              oneOf:
                - type: string
                - type: number
                - type: boolean
                - type: 'null'
    ErrorResponse:
      type: object
      additionalProperties: false
      required:
        - error
      properties:
        error:
          type: object
          additionalProperties: false
          required:
            - code
            - message
            - request_id
          properties:
            code:
              $ref: '#/components/schemas/ErrorCode'
            message:
              type: string
            request_id:
              type: string
            details:
              type: object
              additionalProperties: true
    TrackingNumberSummary:
      type: object
      additionalProperties: false
      required:
        - label
        - phone_last4
        - national_format
      properties:
        label:
          type:
            - string
            - 'null'
        phone_last4:
          type:
            - string
            - 'null'
        national_format:
          type:
            - string
            - 'null'
    ErrorCode:
      type: string
      enum:
        - UNAUTHORIZED
        - FORBIDDEN
        - RATE_LIMITED
        - VALIDATION_ERROR
        - NOT_FOUND
        - CONFLICT
        - INSUFFICIENT_CREDITS
        - INTERNAL_ERROR
  headers:
    IdempotencyReplayed:
      description: >-
        Presente y true cuando se reprodujo una respuesta de escritura exitosa
        almacenada.
      schema:
        type: string
        enum:
          - 'true'
    Deprecation:
      description: >-
        Presente solo cuando la solicitud envió una fecha/hora sin desfase
        respecto a UTC. Esa forma está obsoleta y se interpretó como UTC. El
        valor es la fecha de obsolescencia de RFC 9745 como `@` seguido de los
        segundos Unix.
      schema:
        type: string
        example: '@1791763200'
    Sunset:
      description: >-
        Presente solo con Deprecation. La HTTP-date de RFC 8594 a partir de la
        cual una fecha/hora sin desfase respecto a UTC devuelve 400.
      schema:
        type: string
        example: Sun, 10 Jan 2027 00:00:00 GMT
    RateLimitLimit:
      description: Cantidad máxima de solicitudes permitidas en la ventana actual.
      schema:
        type: string
    RateLimitRemaining:
      description: Solicitudes restantes en la ventana actual.
      schema:
        type: string
    RateLimitReset:
      description: Timestamp ISO cuando se reinicia la ventana actual de rate limit.
      schema:
        type: string
        format: date-time
    RetryAfter:
      description: Segundos hasta que el llamador debería reintentar.
      schema:
        type: string
  responses:
    ValidationError:
      description: El payload, query o header requerido de la solicitud no es válido.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Unauthorized:
      description: API key ausente, malformada, revocada, eliminada o desconocida.
      headers:
        WWW-Authenticate:
          schema:
            type: string
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Forbidden:
      description: >-
        La API key no tiene un scope requerido, o el workspace no está activo.
        Un fallo de scope indica un scope faltante en `details.required_scope`.
        Cuando la búsqueda de la key rechaza la llamada,
        `details.missing_scopes` lista cada scope requerido que la key no tiene.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            missing_scope:
              summary: Una key de Solo lectura llama a una operación de escritura
              value:
                error:
                  code: FORBIDDEN
                  message: 'API key does not include the required scope: leads.write.'
                  request_id: req_123
                  details:
                    required_scope: leads.write
                    missing_scopes:
                      - leads.write
    NotFound:
      description: Recurso no encontrado en el workspace vinculado a la key.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Conflict:
      description: >-
        La solicitud entra en conflicto con la idempotencia o la identidad del
        evento externo.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    RateLimited:
      description: >-
        Rate limit excedido para esta key y endpoint o para el bucket de
        autenticación inválida.
      headers:
        X-RateLimit-Limit:
          $ref: '#/components/headers/RateLimitLimit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/RateLimitRemaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/RateLimitReset'
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    InternalError:
      description: Error interno de autenticación o del servidor.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
  securitySchemes:
    ApiKeyBearer:
      type: http
      scheme: bearer
      bearerFormat: RoofKit API key
      description: 'Usa `Authorization: Bearer rk_live_...`.'

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.