{
  "openapi": "3.0.3",
  "info": {
    "title": "API de Socios de Firma",
    "description": "API RESTful para firma de documentos y gestión de plantillas.\n\n**Autenticación**: Todos los endpoints requieren autenticación mediante clave API a través del encabezado `Authorization`. Usa tu clave API directamente sin ningún prefijo (por ejemplo, `your-api-key`). El prefijo Bearer es opcional pero no obligatorio.\n\n**Características de Seguridad**:\n- Validación de entrada usando esquemas Zod con mensajes de error detallados a nivel de campo\n- Tokens JWT firmados con RSA-256 para el acceso al Editor de Plantillas incrustado\n\n**Límite de Solicitudes**: Los límites de solicitudes están escalonados según el tipo de operación:\n- Operaciones de lectura (GET): 200 solicitudes por minuto\n- Operaciones de escritura (POST/PUT/PATCH/DELETE): 120 solicitudes por minuto\n- Operaciones CRUD de webhooks: 60 solicitudes por minuto\n- Prueba de webhook: 10 solicitudes por minuto\n- Regeneración/expiración de clave API: 1 solicitud por minuto\n- Rotación de secreto de webhook: 1 solicitud por minuto\n\nCuando se superan los límites de solicitudes, la API devuelve una respuesta `429 Too Many Requests` con los encabezados:\n- `X-RateLimit-Limit`: Máximo de solicitudes por minuto para este endpoint\n- `X-RateLimit-Remaining`: Solicitudes restantes en la ventana actual\n- `X-RateLimit-Reset`: Marca de tiempo Unix de cuándo se restablece el límite\n- `Retry-After`: Segundos hasta que se permita reintentar\n\n**Manejo de Errores**: Todos los errores devuelven respuestas JSON estructuradas con `error` (mensaje legible para humanos), `code` (identificador legible por máquina) y `details` (errores de validación a nivel de campo cuando corresponda).\n\n**Integración del Editor de Plantillas Incrustado**: El Editor de Plantillas de Firma se puede incrustar en tu aplicación usando una biblioteca JavaScript independiente.\n\n```html\n<!-- Carga la biblioteca del Editor de Plantillas de Firma -->\n<script src=\"https://api.firma.dev/functions/v1/embed-proxy/template-editor.js\"></script>\n\n<script>\n// Genera el token JWT vía API primero\nfetch('https://api.firma.dev/functions/v1/signing-request-api/generate-template-token', {\n  method: 'POST',\n  headers: {\n    'Authorization': 'YOUR_API_KEY',\n    'Content-Type': 'application/json'\n  },\n  body: JSON.stringify({\n    companies_workspaces_templates_id: 'template-id'\n  })\n})\n.then(res => res.json())\n.then(data => {\n  // Inicializa el editor con el token JWT\n  window.FirmaTemplateEditor.init({\n    container: '#firma-editor-container',\n    jwt: data.token,\n    templateId: 'template-id',\n    theme: 'dark',\n    readOnly: false,\n    onSave: (savedData) => {\n      console.log('Template saved:', savedData);\n    },\n    onError: (error) => {\n      console.error('Editor error:', error);\n    },\n    onLoad: (template) => {\n      console.log('Template loaded:', template);\n    }\n  });\n});\n</script>\n```",
    "version": "01.30.00",
    "contact": {
      "name": "API Support",
      "url": "https://firma.com/support"
    }
  },
  "servers": [
    {
      "url": "https://api.firma.dev/functions/v1/signing-request-api",
      "description": "API de Producción - Recomendada (Actual)"
    },
    {
      "url": "https://api.firma.dev/api/v1",
      "description": "API de Producción - Planeada"
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    }
  ],
  "tags": [
    {
      "name": "Company",
      "description": "Información y configuración de la empresa"
    },
    {
      "name": "Workspaces",
      "description": "Operaciones de gestión de espacios de trabajo"
    },
    {
      "name": "Templates",
      "description": "Operaciones de gestión de plantillas"
    },
    {
      "name": "Signing Requests",
      "description": "Operaciones de solicitudes de firma de documentos"
    },
    {
      "name": "Custom Fields",
      "description": "Gestión de definiciones de campos personalizados para espacios de trabajo, plantillas y solicitudes de firma"
    },
    {
      "name": "Webhooks",
      "description": "Configuración y gestión de webhooks"
    },
    {
      "name": "JWT Management",
      "description": "Generación y revocación de tokens JWT para plantillas incrustadas"
    },
    {
      "name": "Workspace Settings",
      "description": "Configuración y ajustes del espacio de trabajo"
    },
    {
      "name": "Email Domains",
      "description": "Configuración y verificación de dominios de correo electrónico para enviar correos de solicitudes de firma desde dominios personalizados"
    },
    {
      "name": "Email Templates",
      "description": "Gestión de plantillas de correo electrónico para personalización de notificaciones de solicitudes de firma a nivel de espacio de trabajo y de empresa"
    },
    {
      "name": "Signer Terms",
      "description": "Términos de servicio / declaraciones de consentimiento personalizadas del firmante, a nivel de empresa con anulaciones por espacio de trabajo según el idioma"
    }
  ],
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "Authorization",
        "description": "Clave API para autenticación. Usa tu clave API directamente sin ningún prefijo (por ejemplo, 'your-api-key'). El prefijo Bearer es opcional pero no obligatorio."
      }
    },
    "responses": {
      "ValidationError": {
        "description": "Solicitud Incorrecta - La validación falló",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "Validation Error",
              "message": "Invalid input data",
              "details": {
                "name": "Name is required",
                "email": "Invalid email format"
              }
            }
          }
        }
      },
      "UnauthorizedError": {
        "description": "No Autorizado - Clave API inválida o faltante",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "Unauthorized",
              "message": "Invalid API key"
            }
          }
        }
      },
      "ForbiddenError": {
        "description": "Prohibido - Permisos insuficientes",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "Forbidden",
              "message": "You do not have permission to access this resource"
            }
          }
        }
      },
      "NotFoundError": {
        "description": "No Encontrado - El recurso no existe",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "Not Found",
              "message": "The requested resource was not found"
            }
          }
        }
      },
      "RateLimitError": {
        "description": "Demasiadas Solicitudes - Se superó el límite de solicitudes",
        "headers": {
          "X-RateLimit-Limit": {
            "schema": {
              "type": "integer"
            },
            "description": "Número máximo de solicitudes por minuto"
          },
          "X-RateLimit-Remaining": {
            "schema": {
              "type": "integer"
            },
            "description": "Solicitudes restantes"
          },
          "X-RateLimit-Reset": {
            "schema": {
              "type": "integer"
            },
            "description": "Marca de tiempo Unix del reinicio"
          },
          "Retry-After": {
            "schema": {
              "type": "integer"
            },
            "description": "Segundos hasta que se permita reintentar"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "Rate Limit Exceeded",
              "message": "Too many requests. Please wait before retrying.",
              "details": {
                "retry_after": 45
              }
            }
          }
        }
      }
    },
    "requestBodies": {
      "PatchSigningRequestBody": {
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/PatchSigningRequestBodySchema"
            },
            "examples": {
              "update-properties": {
                "summary": "Actualizar propiedades",
                "value": {
                  "name": "Updated Contract Name",
                  "expiration_hours": 72
                }
              },
              "update-recipient": {
                "summary": "Actualizar un solo destinatario",
                "value": {
                  "recipient": {
                    "id": "rec123-e89b-12d3-a456-426614174000",
                    "first_name": "John",
                    "last_name": "Smith",
                    "email": "john.smith@example.com",
                    "designation": "Signer",
                    "order": 1
                  }
                }
              },
              "add-recipient": {
                "summary": "Añadir nuevo destinatario",
                "value": {
                  "recipient": {
                    "first_name": "Jane",
                    "last_name": "Doe",
                    "email": "jane@example.com",
                    "designation": "Signer",
                    "order": 2
                  }
                }
              },
              "add-date-field": {
                "summary": "Añadir campo de fecha con formato",
                "value": {
                  "field": {
                    "type": "date",
                    "position": {
                      "x": 70,
                      "y": 45,
                      "width": 15,
                      "height": 3
                    },
                    "page_number": 1,
                    "required": true,
                    "recipient_id": "rec123-e89b-12d3-a456-426614174000",
                    "date_signing_default": true,
                    "format_rules": {
                      "dateFormat": "MMMM dd, yyyy"
                    }
                  }
                }
              },
              "add-read-only-static-field": {
                "summary": "Añadir campo de solo lectura con valor estático",
                "description": "Crea un campo de texto que muestra un valor fijo que el firmante no puede editar",
                "value": {
                  "field": {
                    "type": "text",
                    "position": {
                      "x": 15,
                      "y": 20,
                      "width": 40,
                      "height": 3
                    },
                    "page_number": 1,
                    "required": false,
                    "recipient_id": "rec123-e89b-12d3-a456-426614174000",
                    "read_only": true,
                    "read_only_value": "Contract #12345 - Acme Corporation"
                  }
                }
              },
              "add-read-only-prefilled-field": {
                "summary": "Añadir campo de solo lectura con datos del destinatario",
                "description": "Crea un campo de texto que se autocompleta con el correo electrónico del destinatario (el firmante no puede editarlo)",
                "value": {
                  "field": {
                    "type": "text",
                    "position": {
                      "x": 15,
                      "y": 30,
                      "width": 30,
                      "height": 3
                    },
                    "page_number": 1,
                    "required": false,
                    "recipient_id": "rec123-e89b-12d3-a456-426614174000",
                    "read_only": true,
                    "prefilled_data": "email"
                  }
                }
              }
            }
          }
        }
      },
      "UpdateSigningRequestBody": {
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/UpdateSigningRequestBodySchema"
            },
            "examples": {
              "comprehensive-update": {
                "summary": "Actualización completa con todas las secciones",
                "value": {
                  "signing_request_properties": {
                    "name": "Updated Contract Name",
                    "expiration_hours": 72
                  },
                  "recipients": [
                    {
                      "id": "rec1-e89b-12d3-a456-426614174000",
                      "first_name": "John",
                      "last_name": "Smith",
                      "email": "john.smith@example.com",
                      "designation": "Signer",
                      "order": 1
                    },
                    {
                      "first_name": "Jane",
                      "last_name": "Doe",
                      "email": "jane@example.com",
                      "designation": "Signer",
                      "order": 2
                    }
                  ],
                  "deleted_recipients": [
                    {
                      "recipient_id": "rec2-e89b-12d3-a456-426614174000",
                      "field_action": "reassign",
                      "reassign_to_recipient_id": "rec1-e89b-12d3-a456-426614174000"
                    }
                  ],
                  "fields": [
                    {
                      "id": "field1-e89b-12d3-a456-426614174000",
                      "type": "signature",
                      "position": {
                        "x": 15,
                        "y": 85,
                        "width": 30,
                        "height": 10
                      },
                      "page_number": 1,
                      "required": true,
                      "recipient_id": "rec1-e89b-12d3-a456-426614174000"
                    }
                  ],
                  "reminders": [
                    {
                      "hours": 48,
                      "all_users": true,
                      "subject": "Reminder: Please sign the document",
                      "message": "This is a reminder to complete your signature."
                    }
                  ]
                }
              },
              "update-with-temp-ids": {
                "summary": "Actualizar con nuevos destinatarios usando IDs temporales",
                "description": "Actualización completa que añade nuevos destinatarios con IDs temporales junto a los destinatarios existentes",
                "value": {
                  "signing_request_properties": {
                    "name": "Updated NDA Agreement"
                  },
                  "recipients": [
                    {
                      "id": "existing-recipient-uuid",
                      "email": "updated@example.com"
                    },
                    {
                      "_temp_id": "temp_new_signer",
                      "first_name": "New",
                      "last_name": "Signer",
                      "email": "newsigner@example.com",
                      "designation": "Signer",
                      "order": 2
                    }
                  ],
                  "fields": [
                    {
                      "id": "existing-field-uuid",
                      "position": {
                        "x": 10,
                        "y": 70,
                        "width": 30,
                        "height": 10
                      }
                    },
                    {
                      "recipient_id": "temp_new_signer",
                      "type": "signature",
                      "page_number": 1,
                      "position": {
                        "x": 10,
                        "y": 55,
                        "width": 30,
                        "height": 10
                      },
                      "required": true
                    }
                  ],
                  "reminders": [
                    {
                      "recipient_id": "temp_new_signer",
                      "hours": 24,
                      "all_users": false,
                      "subject": "Reminder: Sign Document",
                      "message": "Please sign the updated NDA."
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "schemas": {
      "Company": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identificador único de la empresa"
          },
          "name": {
            "type": "string",
            "description": "Nombre de la empresa",
            "maxLength": 255
          },
          "language": {
            "type": "string",
            "description": "Idioma predeterminado de la empresa",
            "enum": [
              "en",
              "es",
              "it",
              "pt",
              "fr",
              "de",
              "el",
              "ru",
              "pl"
            ],
            "default": "en"
          },
          "account_owner": {
            "type": "string",
            "description": "Nombre del propietario de la cuenta",
            "maxLength": 255
          },
          "account_owner_email": {
            "type": "string",
            "format": "email",
            "description": "Dirección de correo electrónico del propietario de la cuenta"
          },
          "website": {
            "type": "string",
            "format": "uri",
            "description": "URL del sitio web de la empresa",
            "nullable": true
          },
          "icon_url": {
            "type": "string",
            "format": "uri",
            "description": "URL de acceso público a la imagen del logo de la empresa. Devuelve null si no hay un logo configurado.",
            "nullable": true,
            "example": "https://ielmshcswdhuacyjlpiy.supabase.co/functions/v1/logo/company/3feb35a8-5aaf-4603-8b50-acd807176b38"
          },
          "credits": {
            "type": "integer",
            "description": "Créditos disponibles para la empresa (solo lectura, gestionado internamente)",
            "minimum": 0,
            "readOnly": true
          },
          "created_date": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de creación de la cuenta de la empresa"
          },
          "updated_date": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de la última actualización de la cuenta de la empresa"
          }
        },
        "required": [
          "id",
          "name",
          "account_owner",
          "account_owner_email",
          "created_date"
        ]
      },
      "Workspace": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identificador único del espacio de trabajo"
          },
          "name": {
            "type": "string",
            "description": "Nombre del espacio de trabajo",
            "maxLength": 255
          },
          "protected": {
            "type": "boolean",
            "description": "Los espacios de trabajo protegidos no se pueden eliminar"
          },
          "api_key": {
            "type": "string",
            "description": "Clave API de modo real para este espacio de trabajo. Se usa para autenticar solicitudes de API limitadas a este espacio de trabajo.",
            "nullable": true
          },
          "test_api_key": {
            "type": "string",
            "description": "Clave API de modo de prueba para este espacio de trabajo. Las solicitudes autenticadas con esta clave no consumen créditos y generan solicitudes de firma marcadas como de prueba, con marca de agua.",
            "nullable": true
          },
          "created_date": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de creación del espacio de trabajo"
          },
          "updated_date": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de la última actualización del espacio de trabajo"
          },
          "webhook_enabled": {
            "type": "boolean",
            "description": "Indica si los webhooks a nivel de espacio de trabajo están habilitados"
          },
          "webhook_secret": {
            "type": "string",
            "description": "Secreto de firma de webhook para este espacio de trabajo",
            "nullable": true
          },
          "webhook_secret_rotated_at": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de la última rotación del secreto de webhook",
            "nullable": true
          },
          "webhook_secret_created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de cuando se creó el secreto de webhook por primera vez",
            "nullable": true
          },
          "ignore_company_webhooks": {
            "type": "boolean",
            "description": "Cuando es true, los webhooks a nivel de empresa no se disparan para eventos en este espacio de trabajo"
          },
          "icon_url": {
            "type": "string",
            "format": "uri",
            "description": "URL de acceso público a la imagen del logo del espacio de trabajo. Devuelve el logo específico del espacio de trabajo, o null si no está configurado (el logo de la empresa NO se incluye como alternativa en este campo).",
            "nullable": true,
            "example": "https://ielmshcswdhuacyjlpiy.supabase.co/functions/v1/logo/workspace/company-id/workspace-id"
          }
        },
        "required": [
          "id",
          "name",
          "created_date"
        ]
      },
      "Template": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identificador único de la plantilla"
          },
          "name": {
            "type": "string",
            "description": "Nombre de la plantilla",
            "maxLength": 255
          },
          "description": {
            "type": "string",
            "description": "Descripción de la plantilla",
            "nullable": true
          },
          "document_url": {
            "type": "string",
            "format": "uri",
            "description": "URL prefirmada al documento PDF. Es una URL firmada con tiempo limitado para acceso seguro; consulta document_url_expires_at para conocer el momento de expiración. Las URLs iniciales son válidas por 7 días; las URLs renovadas son válidas por 1 hora. Solicita una nueva recuperación de la plantilla para obtener una URL nueva si ha expirado."
          },
          "document_url_expires_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Marca de tiempo ISO 8601 de cuándo expirará document_url. Después de este momento, la URL devolverá un error de acceso denegado. Vuelve a obtener la plantilla para recibir una nueva URL firmada."
          },
          "page_count": {
            "type": "integer",
            "minimum": 1,
            "description": "Número de páginas del documento"
          },
          "expiration_hours": {
            "type": "integer",
            "minimum": 1,
            "default": 168,
            "description": "Horas hasta que expiren las solicitudes de firma creadas a partir de esta plantilla"
          },
          "credit_cost": {
            "type": "integer",
            "minimum": 1,
            "default": 1,
            "description": "Número de créditos consumidos cuando se envía una solicitud de firma desde esta plantilla. El valor mínimo es 1."
          },
          "settings": {
            "$ref": "#/components/schemas/SigningRequestSettings"
          },
          "recipients": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TemplateUser"
            },
            "description": "Destinatarios de la plantilla (incluido en GET de una sola plantilla)"
          },
          "fields": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TemplateField"
            },
            "description": "Campos de la plantilla (incluido en GET de una sola plantilla)"
          },
          "created_date": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de creación de la plantilla"
          },
          "updated_date": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de la última actualización de la plantilla"
          }
        },
        "required": [
          "id",
          "name",
          "created_date"
        ]
      },
      "TemplateUser": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identificador único del usuario de la plantilla"
          },
          "name": {
            "type": "string",
            "description": "Nombre del destinatario (nombre y apellido combinados)"
          },
          "email": {
            "type": "string",
            "format": "email",
            "description": "Dirección de correo electrónico del destinatario"
          },
          "first_name": {
            "type": "string",
            "nullable": true,
            "description": "Nombre del destinatario"
          },
          "last_name": {
            "type": "string",
            "nullable": true,
            "description": "Apellido del destinatario"
          },
          "designation": {
            "type": "string",
            "enum": [
              "Signer",
              "Approver",
              "CC"
            ],
            "description": "Rol del destinatario. Signer firma el documento, Approver aprueba con campos de aprobación, CC recibe una copia al finalizar."
          },
          "order": {
            "type": "integer",
            "minimum": 1,
            "description": "Orden en el que el destinatario debe firmar"
          },
          "phone_number": {
            "type": "string",
            "nullable": true,
            "description": "Número de teléfono del destinatario"
          },
          "street_address": {
            "type": "string",
            "nullable": true,
            "description": "Dirección postal del destinatario"
          },
          "city": {
            "type": "string",
            "nullable": true,
            "description": "Ciudad del destinatario"
          },
          "state_province": {
            "type": "string",
            "nullable": true,
            "description": "Estado o provincia del destinatario"
          },
          "postal_code": {
            "type": "string",
            "nullable": true,
            "description": "Código postal del destinatario"
          },
          "country": {
            "type": "string",
            "nullable": true,
            "description": "País del destinatario"
          },
          "title": {
            "type": "string",
            "nullable": true,
            "description": "Cargo del destinatario"
          },
          "company": {
            "type": "string",
            "nullable": true,
            "description": "Nombre de la empresa del destinatario"
          },
          "required_fields": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Lista de campos de datos del destinatario requeridos para el envío (basada en los campos de la plantilla con asignaciones de variable_name). Siempre incluye 'email' y 'first_name'."
          },
          "missing_fields": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Lista de campos requeridos que actualmente están vacíos para este destinatario"
          },
          "required_read_only_fields": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "variable_name": {
                  "type": "string",
                  "nullable": true,
                  "description": "Nombre de variable del campo de solo lectura"
                },
                "variable_defined_name": {
                  "type": "string",
                  "nullable": true,
                  "description": "Nombre del campo legible para humanos, tomado de la definición del campo personalizado (por ejemplo, 'artist_name'). Solo está presente para campos vinculados a una definición de campo personalizado; de lo contrario es null."
                },
                "field_type": {
                  "type": "string",
                  "description": "Tipo del campo (text, date, etc.)"
                }
              }
            },
            "description": "Lista de campos obligatorios de solo lectura que necesitan valores prellenados antes de enviar"
          },
          "ready_to_send": {
            "type": "boolean",
            "description": "Indica si este destinatario tiene todos los datos obligatorios completados para poder enviarse"
          }
        },
        "required": [
          "id",
          "first_name",
          "email",
          "designation",
          "order"
        ]
      },
      "DateFormatRules": {
        "type": "object",
        "description": "Reglas de formato para campos de fecha. Especifica cómo deben mostrarse y formatearse los valores de fecha.",
        "properties": {
          "dateFormat": {
            "type": "string",
            "description": "Patrón de formato de fecha. Usa formatos predefinidos o patrones personalizados con: yyyy (año de 4 dígitos), MM (mes de 2 dígitos), dd (día de 2 dígitos), MMMM (nombre completo del mes), MMM (nombre abreviado del mes), HH (hora en formato 24 horas), mm (minuto), ss (segundo). Ejemplos: 'MM/dd/yyyy' se muestra como 01/31/2024, 'MMMM dd, yyyy' se muestra como January 31, 2024.",
            "enum": [
              "MM/dd/yyyy",
              "dd/MM/yyyy",
              "yyyy-MM-dd",
              "MMMM dd, yyyy",
              "MMM dd, yyyy",
              "dd MMMM yyyy"
            ],
            "default": "MM/dd/yyyy"
          }
        },
        "example": {
          "dateFormat": "MMMM dd, yyyy"
        }
      },
      "FileFormatRules": {
        "type": "object",
        "description": "Reglas de formato para campos de carga de archivos. Especifica qué tipos de archivo pueden subir los firmantes.",
        "properties": {
          "acceptedFileTypes": {
            "type": "string",
            "enum": [
              "image_and_pdf",
              "image",
              "pdf"
            ],
            "default": "image_and_pdf",
            "description": "Tipos de archivo aceptados para la carga. 'image_and_pdf' acepta JPG, PNG y PDF. 'image' acepta solo JPG y PNG. 'pdf' acepta solo PDF. Los archivos se validan por sus bytes mágicos (magic bytes), no solo por la extensión. El tamaño máximo de archivo es 10MB."
          }
        },
        "example": {
          "acceptedFileTypes": "image_and_pdf"
        }
      },
      "FieldValidationRules": {
        "type": "object",
        "nullable": true,
        "description": "Reglas de validación para valores de campo. Reservado para uso futuro: actualmente no se aplica a ningún tipo de campo.",
        "additionalProperties": true
      },
      "TemplateField": {
        "type": "object",
        "description": "Un campo colocado en un documento de plantilla",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identificador único del campo"
          },
          "type": {
            "type": "string",
            "enum": [
              "text",
              "signature",
              "date",
              "checkbox",
              "dropdown",
              "radio_buttons",
              "number",
              "text_area",
              "file",
              "initial",
              "stamp",
              "approval_signature",
              "approval_checkmark",
              "approval_date"
            ],
            "description": "Tipo del campo"
          },
          "required": {
            "type": "boolean",
            "description": "Indica si el campo es obligatorio"
          },
          "recipient_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID del destinatario asignado"
          },
          "variable_name": {
            "type": "string",
            "nullable": true,
            "description": "Nombre de variable del campo (usado en plantillas)"
          },
          "variable_defined_name": {
            "type": "string",
            "nullable": true,
            "description": "Nombre del campo legible para humanos, tomado de la definición del campo personalizado (por ejemplo, 'artist_name'). Solo está presente para campos vinculados a una definición de campo personalizado; de lo contrario es null."
          },
          "position": {
            "type": "object",
            "description": "Posición y dimensiones del campo en el documento. Todos los valores son porcentajes (0-100). El campo debe caber dentro de la página: x + width <= 100 y y + height <= 100.",
            "properties": {
              "x": {
                "type": "number",
                "minimum": 0,
                "maximum": 100,
                "description": "Coordenada X de la posición del campo (porcentaje, 0-100)"
              },
              "y": {
                "type": "number",
                "minimum": 0,
                "maximum": 100,
                "description": "Coordenada Y de la posición del campo (porcentaje, 0-100)"
              },
              "width": {
                "type": "number",
                "minimum": 0,
                "maximum": 100,
                "description": "Ancho del campo (porcentaje, 0-100). Nota: x + width debe ser <= 100"
              },
              "height": {
                "type": "number",
                "minimum": 0,
                "maximum": 100,
                "description": "Alto del campo (porcentaje, 0-100). Nota: y + height debe ser <= 100"
              }
            }
          },
          "page_number": {
            "type": "integer",
            "minimum": 1,
            "nullable": true,
            "description": "Número de página donde se encuentra el campo (empieza en 1). No debe superar el total de páginas del documento."
          },
          "dropdown_options": {
            "nullable": true,
            "description": "Opciones para campos desplegables",
            "oneOf": [
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              {
                "type": "object"
              }
            ]
          },
          "multi_group_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID de grupo para vincular varios campos de casilla de verificación o botón de opción entre sí. Los campos que comparten el mismo multi_group_id se comportan como un grupo mutuamente excluyente (como botones de opción): seleccionar uno deselecciona automáticamente los demás del grupo. Usa el mismo UUID en varios campos para crear un grupo donde solo se puede seleccionar una opción a la vez."
          },
          "date_default": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Valor de fecha predeterminado para campos de fecha (formato ISO 8601, por ejemplo, '2024-01-15')"
          },
          "date_signing_default": {
            "type": "boolean",
            "description": "Usar la fecha de firma como valor predeterminado para campos de fecha"
          },
          "format_rules": {
            "$ref": "#/components/schemas/DateFormatRules",
            "nullable": true,
            "description": "Reglas de formato: actualmente se usan para campos de fecha, para especificar el formato de visualización"
          },
          "validation_rules": {
            "$ref": "#/components/schemas/FieldValidationRules"
          },
          "read_only": {
            "type": "boolean",
            "default": false,
            "description": "Indica si este campo es de solo lectura (prellenado antes de firmar)"
          },
          "read_only_value": {
            "type": "string",
            "nullable": true,
            "description": "Valor estático para campos de solo lectura"
          }
        },
        "required": [
          "id",
          "type",
          "page_number"
        ]
      },
      "Reminder": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identificador único del recordatorio"
          },
          "hours": {
            "type": "integer",
            "minimum": 1,
            "description": "Horas después del envío antes de que se envíe el recordatorio"
          },
          "subject": {
            "type": "string",
            "description": "Asunto del correo para el recordatorio",
            "maxLength": 255
          },
          "message": {
            "type": "string",
            "description": "Cuerpo del mensaje de correo para el recordatorio",
            "maxLength": 5000
          },
          "all_users": {
            "type": "boolean",
            "description": "Indica si el recordatorio aplica a todos los usuarios"
          },
          "template_user_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "Usuario específico al que se le enviará el recordatorio (usado en el contexto de plantilla)"
          },
          "recipient_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "Destinatario específico al que se le enviará el recordatorio (usado en el contexto de solicitud de firma, es lo mismo que template_user_id)"
          },
          "sent_on": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Marca de tiempo de cuándo se envió realmente el recordatorio"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de creación del recordatorio"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de la última actualización del recordatorio"
          }
        },
        "required": [
          "id",
          "hours",
          "subject",
          "message"
        ]
      },
      "SigningRequestListItem": {
        "type": "object",
        "description": "Solicitud de firma tal como la devuelve el endpoint LIST (GET /signing-requests)",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identificador único de la solicitud de firma"
          },
          "name": {
            "type": "string",
            "description": "Nombre de la solicitud de firma",
            "maxLength": 255
          },
          "description": {
            "type": "string",
            "nullable": true,
            "description": "Descripción de la solicitud de firma"
          },
          "status": {
            "type": "string",
            "enum": [
              "not_sent",
              "in_progress",
              "finished",
              "cancelled",
              "declined",
              "deleted",
              "expired"
            ],
            "description": "Estado actual de la solicitud de firma"
          },
          "document_url": {
            "type": "string",
            "format": "uri",
            "description": "URL prefirmada al documento PDF. Es una URL firmada de tiempo limitado para acceso seguro - ver document_url_expires_at para el tiempo de expiración. Las URLs iniciales son válidas por 7 días; las URLs renovadas son válidas por 1 hora. Solicita una nueva recuperación de la solicitud de firma para obtener una URL nueva si ha expirado."
          },
          "document_url_expires_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Marca de tiempo ISO 8601 de cuándo expirará document_url. Después de este momento, la URL devolverá un error de acceso denegado. Vuelve a obtener la solicitud de firma para recibir una URL firmada nueva."
          },
          "page_count": {
            "type": "integer",
            "minimum": 1,
            "description": "Número de páginas en el documento"
          },
          "expiration_hours": {
            "type": "integer",
            "minimum": 1,
            "default": 168,
            "description": "Horas hasta que la solicitud de firma expire (por defecto: 168 = 7 días)"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Marca de tiempo ISO 8601 de cuándo expira la solicitud de firma. Se calcula a partir de sent_date + expiration_hours. Es nulo si la solicitud de firma aún no ha sido enviada o no tiene expiration_hours configurado."
          },
          "credit_cost": {
            "type": "integer",
            "minimum": 1,
            "default": 1,
            "description": "Número de créditos consumidos cuando se envió esta solicitud de firma. El valor mínimo es 1."
          },
          "template_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID de la plantilla si se creó a partir de una plantilla"
          },
          "settings": {
            "$ref": "#/components/schemas/SigningRequestSettings"
          },
          "created_date": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de creación"
          },
          "updated_date": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de la última actualización"
          },
          "sent_date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Cuándo se envió la solicitud de firma"
          },
          "finished_date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Cuándo se completaron todas las firmas"
          },
          "cancelled_date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Cuándo se canceló la solicitud de firma"
          },
          "declined_date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Cuándo se rechazó la solicitud de firma"
          },
          "recipients": {
            "type": "array",
            "description": "Destinatarios de la solicitud de firma (formato simplificado)",
            "items": {
              "$ref": "#/components/schemas/SigningRequestListRecipient"
            }
          },
          "fields": {
            "type": "array",
            "description": "Campos de la solicitud de firma con objeto de posición anidado",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "type": {
                  "type": "string",
                  "enum": [
                    "text",
                    "signature",
                    "date",
                    "checkbox",
                    "dropdown",
                    "radio_buttons",
                    "number",
                    "text_area",
                    "file",
                    "initial",
                    "stamp",
                    "approval_signature",
                    "approval_checkmark",
                    "approval_date"
                  ]
                },
                "required": {
                  "type": "boolean"
                },
                "recipient_id": {
                  "type": "string",
                  "format": "uuid",
                  "nullable": true
                },
                "variable_name": {
                  "type": "string",
                  "nullable": true
                },
                "variable_defined_name": {
                  "type": "string",
                  "nullable": true,
                  "description": "Nombre de campo legible tomado de la definición del campo personalizado (por ejemplo, 'artist_name'). Solo está presente para campos vinculados a una definición de campo personalizado; de lo contrario es nulo."
                },
                "position": {
                  "type": "object",
                  "properties": {
                    "x": {
                      "type": "number"
                    },
                    "y": {
                      "type": "number"
                    },
                    "width": {
                      "type": "number"
                    },
                    "height": {
                      "type": "number"
                    }
                  }
                },
                "value": {
                  "type": "string",
                  "nullable": true,
                  "description": "Valor final del campo después de firmar"
                },
                "dropdown_options": {
                  "nullable": true,
                  "oneOf": [
                    {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    {
                      "type": "object"
                    }
                  ]
                },
                "format_rules": {
                  "$ref": "#/components/schemas/DateFormatRules",
                  "nullable": true
                },
                "validation_rules": {
                  "$ref": "#/components/schemas/FieldValidationRules"
                }
              }
            }
          }
        },
        "required": [
          "id",
          "name",
          "status",
          "created_date"
        ]
      },
      "SigningRequestListRecipient": {
        "type": "object",
        "description": "Destinatario tal como se devuelve en las respuestas LIST de solicitudes de firma (formato simplificado)",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identificador único del destinatario"
          },
          "name": {
            "type": "string",
            "description": "Nombre completo combinado"
          },
          "email": {
            "type": "string",
            "format": "email",
            "description": "Dirección de correo electrónico del destinatario"
          },
          "designation": {
            "type": "string",
            "enum": [
              "Signer",
              "Approver",
              "CC"
            ],
            "description": "Rol del destinatario. El Firmante firma el documento, el Aprobador aprueba con campos de aprobación, CC recibe una copia cuando se completa."
          },
          "order": {
            "type": "integer",
            "minimum": 1,
            "description": "Orden de firma"
          },
          "finished_date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Cuándo este destinatario completó la firma"
          },
          "signature_details": {
            "type": "object",
            "nullable": true,
            "description": "Detalles sobre la firma del destinatario"
          }
        }
      },
      "SigningRequestCreateResponse": {
        "type": "object",
        "description": "Solicitud de firma tal como la devuelven los endpoints CREATE (POST /signing-requests)",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identificador único de la solicitud de firma"
          },
          "name": {
            "type": "string",
            "description": "Nombre de la solicitud de firma",
            "maxLength": 255
          },
          "description": {
            "type": "string",
            "nullable": true,
            "description": "Descripción de la solicitud de firma"
          },
          "status": {
            "type": "string",
            "enum": [
              "draft"
            ],
            "description": "El status siempre es 'draft' para solicitudes de firma recién creadas"
          },
          "document_url": {
            "type": "string",
            "format": "uri",
            "description": "URL prefirmada al documento PDF"
          },
          "page_count": {
            "type": "integer",
            "minimum": 1,
            "description": "Número de páginas en el documento"
          },
          "expiration_hours": {
            "type": "integer",
            "minimum": 1,
            "default": 168,
            "description": "Horas hasta que la solicitud de firma expire (por defecto: 168 = 7 días)"
          },
          "template_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID de la plantilla si se creó a partir de una plantilla"
          },
          "settings": {
            "$ref": "#/components/schemas/SigningRequestSettings"
          },
          "created_date": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de creación"
          },
          "updated_date": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de la última actualización"
          },
          "sent_date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Cuándo se envió la solicitud de firma"
          },
          "finished_date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Cuándo se completaron todas las firmas"
          },
          "cancelled_date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Cuándo se canceló la solicitud de firma"
          },
          "recipients": {
            "type": "array",
            "description": "Destinatarios de la solicitud de firma",
            "items": {
              "$ref": "#/components/schemas/SigningRequestCreateRecipient"
            }
          },
          "fields": {
            "type": "array",
            "description": "Campos de la solicitud de firma con valores de posición planos",
            "items": {
              "$ref": "#/components/schemas/SigningRequestCreateField"
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Advertencias opcionales de validación de formato de correo electrónico. Solo están presentes cuando los correos electrónicos de los destinatarios tienen formatos inusuales."
          }
        },
        "required": [
          "id",
          "name",
          "status"
        ]
      },
      "SigningRequestCreateRecipient": {
        "type": "object",
        "description": "Destinatario tal como se devuelve en las respuestas CREATE de solicitudes de firma",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identificador único del destinatario"
          },
          "first_name": {
            "type": "string",
            "nullable": true,
            "description": "Nombre del destinatario"
          },
          "last_name": {
            "type": "string",
            "nullable": true,
            "description": "Apellido del destinatario"
          },
          "name": {
            "type": "string",
            "nullable": true,
            "description": "Nombre completo combinado (construido automáticamente a partir de first_name + last_name)"
          },
          "email": {
            "type": "string",
            "format": "email",
            "description": "Dirección de correo electrónico del destinatario"
          },
          "designation": {
            "type": "string",
            "enum": [
              "Signer",
              "Approver",
              "CC"
            ],
            "description": "Rol del destinatario. El Firmante firma el documento, el Aprobador aprueba con campos de aprobación, CC recibe una copia cuando se completa."
          },
          "order": {
            "type": "integer",
            "minimum": 1,
            "description": "Orden de firma"
          },
          "phone_number": {
            "type": "string",
            "nullable": true,
            "description": "Número de teléfono del destinatario"
          },
          "street_address": {
            "type": "string",
            "nullable": true,
            "description": "Dirección postal"
          },
          "city": {
            "type": "string",
            "nullable": true,
            "description": "Ciudad"
          },
          "state_province": {
            "type": "string",
            "nullable": true,
            "description": "Estado o provincia"
          },
          "postal_code": {
            "type": "string",
            "nullable": true,
            "description": "Código postal"
          },
          "country": {
            "type": "string",
            "nullable": true,
            "description": "País"
          },
          "title": {
            "type": "string",
            "nullable": true,
            "description": "Puesto de trabajo"
          },
          "company": {
            "type": "string",
            "nullable": true,
            "description": "Nombre de la empresa"
          },
          "custom_fields": {
            "type": "object",
            "nullable": true,
            "description": "Pares clave-valor personalizados"
          },
          "finished_date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Cuándo este destinatario completó la firma"
          }
        },
        "required": [
          "first_name",
          "email",
          "designation"
        ]
      },
      "SigningRequestCreateField": {
        "type": "object",
        "description": "Campo tal como se devuelve en las respuestas CREATE de solicitudes de firma (posición plana, estilo base de datos)",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identificador único del campo"
          },
          "type": {
            "type": "string",
            "enum": [
              "text",
              "signature",
              "date",
              "checkbox",
              "dropdown",
              "radio_buttons",
              "number",
              "text_area",
              "file",
              "initial",
              "stamp",
              "approval_signature",
              "approval_checkmark",
              "approval_date"
            ],
            "description": "Tipo del campo"
          },
          "recipient_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID del destinatario asignado"
          },
          "page_number": {
            "type": "integer",
            "minimum": 1,
            "description": "Número de página (indexado desde 1)"
          },
          "x_position": {
            "type": "number",
            "description": "Coordenada X como porcentaje (0-100)"
          },
          "y_position": {
            "type": "number",
            "description": "Coordenada Y como porcentaje (0-100)"
          },
          "width": {
            "type": "number",
            "description": "Ancho como porcentaje (0-100)"
          },
          "height": {
            "type": "number",
            "description": "Alto como porcentaje (0-100)"
          },
          "required": {
            "type": "boolean",
            "description": "Indica si el campo es obligatorio"
          },
          "read_only": {
            "type": "boolean",
            "description": "Indica si este campo es de solo lectura"
          },
          "read_only_value": {
            "type": "string",
            "nullable": true,
            "description": "Valor estático para campos de solo lectura"
          },
          "variable_name": {
            "type": "string",
            "nullable": true,
            "description": "Nombre de variable para el mapeo de datos prellenados"
          },
          "variable_defined_name": {
            "type": "string",
            "nullable": true,
            "description": "Nombre de campo legible tomado de la definición del campo personalizado (por ejemplo, 'artist_name'). Solo está presente para campos vinculados a una definición de campo personalizado; de lo contrario es nulo."
          },
          "dropdown_options": {
            "nullable": true,
            "description": "Opciones para campos desplegables",
            "oneOf": [
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              {
                "type": "object"
              }
            ]
          },
          "format_rules": {
            "type": "object",
            "nullable": true,
            "description": "Reglas de formato (por ejemplo, formato de fecha)"
          },
          "validation_rules": {
            "type": "object",
            "nullable": true,
            "description": "Reglas de validación para el campo"
          },
          "date_signing_default": {
            "type": "boolean",
            "description": "Si se debe usar la fecha de firma como valor predeterminado"
          },
          "final_value": {
            "type": "string",
            "nullable": true,
            "description": "Valor prellenado o final del campo"
          }
        },
        "required": [
          "type",
          "recipient_id",
          "page_number"
        ]
      },
      "SigningRequestDetail": {
        "type": "object",
        "description": "Solicitud de Firma detallada, tal como la devuelve GET /signing-requests/{id} (forma anidada con objeto status y timestamps)",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identificador único de la Solicitud de Firma"
          },
          "name": {
            "type": "string",
            "description": "Nombre de la Solicitud de Firma"
          },
          "template_description": {
            "type": "string",
            "nullable": true,
            "description": "Descripción de la Plantilla"
          },
          "companies_workspaces_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID del Espacio de Trabajo al que pertenece esta Solicitud de Firma"
          },
          "document_url": {
            "type": "string",
            "format": "uri",
            "description": "URL prefirmada al documento PDF"
          },
          "document_url_expires_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "document_page_count": {
            "type": "integer",
            "minimum": 1,
            "description": "Cantidad de páginas del documento"
          },
          "expiration_hours": {
            "type": "integer",
            "description": "Horas hasta que expira la Solicitud de Firma"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Timestamp ISO 8601 de cuándo expira la Solicitud de Firma. Se calcula a partir de sent_on + expiration_hours. Es null si aún no se envió o si no se estableció expiration_hours."
          },
          "credit_cost": {
            "type": "integer",
            "description": "Créditos consumidos al enviarse"
          },
          "status": {
            "type": "object",
            "description": "Indicadores de estado (pueden ser true varios a la vez en estados terminales)",
            "properties": {
              "sent": {
                "type": "boolean"
              },
              "finished": {
                "type": "boolean"
              },
              "cancelled": {
                "type": "boolean"
              },
              "declined": {
                "type": "boolean"
              },
              "expired": {
                "type": "boolean"
              }
            }
          },
          "timestamps": {
            "type": "object",
            "description": "Todos los timestamps relevantes del ciclo de vida de la Solicitud de Firma",
            "properties": {
              "created_on": {
                "type": "string",
                "format": "date-time"
              },
              "sent_on": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              },
              "finished_on": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              },
              "cancelled_on": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              },
              "declined_on": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              },
              "last_changed_on": {
                "type": "string",
                "format": "date-time"
              },
              "last_signing_action_on": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              }
            }
          },
          "settings": {
            "$ref": "#/components/schemas/SigningRequestSettings"
          },
          "use_signing_order": {
            "type": "integer",
            "enum": [
              0,
              1
            ],
            "deprecated": true
          },
          "allow_download": {
            "type": "integer",
            "enum": [
              0,
              1
            ],
            "deprecated": true
          },
          "allow_editing_before_sending": {
            "type": "integer",
            "enum": [
              0,
              1
            ],
            "deprecated": true
          },
          "hand_drawn_only": {
            "type": "integer",
            "enum": [
              0,
              1
            ],
            "deprecated": true
          },
          "attach_pdf_on_finish": {
            "type": "integer",
            "enum": [
              0,
              1
            ],
            "deprecated": true
          },
          "certificate": {
            "type": "object",
            "nullable": true,
            "description": "Información del estado de generación del certificado",
            "properties": {
              "generated": {
                "type": "boolean",
                "description": "Si el PDF del certificado final ya fue generado"
              },
              "generated_on": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Timestamp de cuándo se generó el certificado"
              },
              "has_error": {
                "type": "boolean",
                "description": "Si hubo un error al generar el certificado"
              }
            }
          },
          "final_document_download_url": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "URL firmada para descargar el documento final firmado (PDF con certificado). La URL expira después de 1 hora."
          },
          "final_document_download_error": {
            "type": "string",
            "nullable": true,
            "enum": [
              "file_not_accessible",
              null
            ]
          },
          "document_only_download_url": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "URL firmada para descargar el PDF solo del documento. La URL expira después de 1 hora."
          },
          "document_only_download_error": {
            "type": "string",
            "nullable": true,
            "enum": [
              "file_not_accessible",
              null
            ]
          },
          "certificate_only_download_url": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "URL firmada para descargar el PDF solo del certificado. La URL expira después de 1 hora."
          },
          "certificate_only_download_error": {
            "type": "string",
            "nullable": true,
            "enum": [
              "file_not_accessible",
              null
            ]
          }
        },
        "required": [
          "id",
          "name",
          "status",
          "companies_workspaces_id"
        ]
      },
      "SigningRequestSettings": {
        "type": "object",
        "description": "Configuración devuelta por los endpoints de listado y detalle de Solicitudes de Firma. Las Plantillas usan el esquema TemplateSettings (sin campos de identidad).",
        "properties": {
          "allow_download": {
            "type": "boolean",
            "description": "Si los destinatarios pueden descargar el documento",
            "default": true
          },
          "attach_pdf_on_finish": {
            "type": "boolean",
            "description": "Si se debe adjuntar el PDF cuando se completa la firma",
            "default": true
          },
          "allow_editing_before_sending": {
            "type": "boolean",
            "description": "Si la Solicitud de Firma se puede editar antes de enviarse",
            "default": false
          },
          "use_signing_order": {
            "type": "boolean",
            "description": "Si se aplica un orden de firma entre los destinatarios. Cuando es true, los Firmantes reciben el documento en secuencia según su order. Cuando es false, todos los Firmantes reciben el documento al mismo tiempo.",
            "default": true
          },
          "hand_drawn_only": {
            "type": "boolean",
            "description": "Cuando está habilitado, los Firmantes solo pueden dibujar su firma a mano y no pueden usar firmas escritas/basadas en fuente",
            "default": false
          },
          "send_signing_email": {
            "type": "boolean",
            "description": "Si se deben enviar correos de notificación de la Solicitud de Firma a los Firmantes",
            "default": true
          },
          "send_finish_email": {
            "type": "boolean",
            "description": "Si se debe enviar un correo de finalización cuando todos los Firmantes terminan",
            "default": true
          },
          "send_expiration_email": {
            "type": "boolean",
            "description": "Si se debe enviar un correo de notificación de expiración cuando la solicitud expira",
            "default": true
          },
          "send_cancellation_email": {
            "type": "boolean",
            "description": "Si se debe enviar un correo de notificación de cancelación cuando se cancela la solicitud",
            "default": true
          },
          "require_otp_verification": {
            "type": "boolean",
            "nullable": true,
            "description": "Si los Firmantes deben verificar su correo con un código de un solo uso antes de acceder al documento. null = hereda la configuración del Espacio de Trabajo/empresa.",
            "default": null
          },
          "disable_guided_navigation": {
            "type": "boolean",
            "nullable": true,
            "description": "Desactiva el desplazamiento automático al siguiente campo requerido durante la firma. Hereda del Espacio de Trabajo o de la empresa si no está configurado."
          },
          "allow_presigning_download": {
            "type": "boolean",
            "nullable": true,
            "description": "Permite a los Firmantes descargar el documento original antes de firmar. Hereda de la configuración del Espacio de Trabajo o de la empresa cuando es null."
          },
          "show_qr_code": {
            "type": "boolean",
            "nullable": true,
            "description": "Muestra un código QR en la página de firma que permite a los Firmantes continuar desde su teléfono. Hereda de la configuración del Espacio de Trabajo o de la empresa cuando es null."
          },
          "identity_editable_fields": {
            "type": "array",
            "nullable": true,
            "items": {
              "type": "string"
            },
            "description": "Campos de identidad que los Firmantes pueden editar antes de firmar (por ejemplo, [\"name\", \"company\"]). null = desactivado. Cuando está configurado, un diálogo de confirmación permite a los Firmantes editar los campos especificados."
          },
          "notify_identity_change_email": {
            "type": "boolean",
            "default": false,
            "description": "Envía una notificación por correo cuando un Firmante cambia su identidad."
          }
        }
      },
      "TemplateSettings": {
        "type": "object",
        "description": "Configuración devuelta por los endpoints de Plantillas. Coincide con SigningRequestSettings menos los campos de identidad del Firmante (identity_editable_fields, notify_identity_change_email), que solo aplican a las Solicitudes de Firma.",
        "properties": {
          "allow_download": {
            "type": "boolean",
            "description": "Si los destinatarios pueden descargar el documento",
            "default": true
          },
          "attach_pdf_on_finish": {
            "type": "boolean",
            "description": "Si se debe adjuntar el PDF cuando se completa la firma",
            "default": true
          },
          "allow_editing_before_sending": {
            "type": "boolean",
            "description": "Si la Solicitud de Firma se puede editar antes de enviarse",
            "default": false
          },
          "use_signing_order": {
            "type": "boolean",
            "description": "Si se aplica un orden de firma entre los destinatarios.",
            "default": true
          },
          "hand_drawn_only": {
            "type": "boolean",
            "description": "Cuando está habilitado, los Firmantes solo pueden dibujar su firma a mano y no pueden usar firmas escritas/basadas en fuente",
            "default": false
          },
          "send_signing_email": {
            "type": "boolean",
            "description": "Si se deben enviar correos de notificación de la Solicitud de Firma a los Firmantes",
            "default": true
          },
          "send_finish_email": {
            "type": "boolean",
            "description": "Si se debe enviar un correo de finalización cuando todos los Firmantes terminan",
            "default": true
          },
          "send_expiration_email": {
            "type": "boolean",
            "description": "Si se debe enviar un correo de notificación de expiración cuando la solicitud expira",
            "default": true
          },
          "send_cancellation_email": {
            "type": "boolean",
            "description": "Indica si se debe enviar un correo de notificación de cancelación cuando se cancela la solicitud",
            "default": true
          },
          "require_otp_verification": {
            "type": "boolean",
            "nullable": true,
            "description": "Indica si los firmantes deben verificar su correo electrónico con un código de un solo uso antes de acceder al documento. null = heredar de la configuración del espacio de trabajo/empresa.",
            "default": null
          },
          "disable_guided_navigation": {
            "type": "boolean",
            "nullable": true,
            "description": "Desactiva el desplazamiento automático al siguiente campo requerido durante la firma. Se hereda del espacio de trabajo o la empresa si no está configurado."
          },
          "allow_presigning_download": {
            "type": "boolean",
            "nullable": true,
            "description": "Permite que los firmantes descarguen el documento original antes de firmar. Se hereda de la configuración del espacio de trabajo o la empresa cuando es null."
          },
          "show_qr_code": {
            "type": "boolean",
            "nullable": true,
            "description": "Muestra un código QR en la página de firma que permite a los firmantes continuar desde su teléfono. Se hereda de la configuración del espacio de trabajo o la empresa cuando es null."
          }
        }
      },
      "LegacyDocumentSettings": {
        "type": "object",
        "description": "Configuración devuelta por el endpoint obsoleto POST /documents. Un conjunto reducido; las integraciones nuevas deben usar los endpoints de solicitud de firma, que devuelven SigningRequestSettings.",
        "properties": {
          "allow_download": {
            "type": "boolean",
            "description": "Indica si los destinatarios pueden descargar el documento",
            "default": true
          },
          "attach_pdf_on_finish": {
            "type": "boolean",
            "description": "Indica si se debe adjuntar el PDF cuando se completa la firma",
            "default": true
          },
          "allow_editing_before_sending": {
            "type": "boolean",
            "description": "Indica si la solicitud de firma se puede editar antes de enviarla",
            "default": false
          },
          "use_signing_order": {
            "type": "boolean",
            "description": "Indica si se exige un orden de firma entre los destinatarios.",
            "default": true
          },
          "hand_drawn_only": {
            "type": "boolean",
            "description": "Cuando está activado, los firmantes solo pueden dibujar su firma a mano",
            "default": false
          },
          "send_signing_email": {
            "type": "boolean",
            "description": "Indica si se deben enviar correos de notificación de solicitud de firma a los firmantes",
            "default": true
          },
          "send_finish_email": {
            "type": "boolean",
            "description": "Indica si se debe enviar un correo de finalización cuando todos los firmantes terminan",
            "default": true
          },
          "send_expiration_email": {
            "type": "boolean",
            "description": "Indica si se debe enviar un correo de notificación de expiración cuando la solicitud expira",
            "default": true
          },
          "send_cancellation_email": {
            "type": "boolean",
            "description": "Indica si se debe enviar un correo de notificación de cancelación cuando se cancela la solicitud",
            "default": true
          },
          "disable_guided_navigation": {
            "type": "boolean",
            "nullable": true,
            "description": "Desactiva el desplazamiento automático al siguiente campo requerido durante la firma. Se hereda del espacio de trabajo o la empresa si no está configurado."
          },
          "allow_presigning_download": {
            "type": "boolean",
            "nullable": true,
            "description": "Permite que los firmantes descarguen el documento original antes de firmar. Se hereda de la configuración del espacio de trabajo o la empresa cuando es null."
          }
        }
      },
      "Recipient": {
        "type": "object",
        "required": [
          "first_name",
          "email",
          "designation"
        ],
        "description": "Esquema de Destinatario con comportamientos de auto-construcción y mapeo. **Campo Name**: Se construye automáticamente a partir de first_name y last_name ('First Last' si ambos están presentes, de lo contrario 'First'). Los valores de name ingresados manualmente se sobrescriben. **Asignación de order**: TODOS los destinatarios DEBEN tener un valor de order explícito. Order determina la secuencia de firma, que siempre se aplica. Los destinatarios deben firmar en orden, firmando primero los números más bajos. **Campos personalizados**: Admite tanto la estructura plana (por ejemplo, company_name en la raíz) como la estructura anidada (objeto custom_fields). Ambos formatos se normalizan internamente. **Mapeo de campos de plantilla**: Al crear a partir de una plantilla con destinatarios personalizados, use template_user_id u order para hacer coincidir a los usuarios de la plantilla. Solo se puede actualizar la información del usuario (name, email, phone, etc.); order y designation se heredan de la plantilla. **IDs temporales**: Para la creación basada en documentos, use IDs temporales (formato: 'temp_1', 'temp_2', etc.) para hacer referencia a los destinatarios en fields y reminders antes de que se creen. **Destinatarios CC**: Los destinatarios en CC reciben una copia completada pero no pueden firmar ni tener campos asignados. Se requiere al menos un Firmante.",
        "properties": {
          "id": {
            "type": "string",
            "description": "Identificador único. Para actualizaciones: use el UUID existente. Para la creación basada en documentos: opcionalmente use un ID temporal (formato: 'temp_1', 'temp_2', etc.) para hacer referencia a los destinatarios en fields y reminders antes de la creación. Los IDs temporales se resuelven automáticamente a UUIDs reales en la respuesta."
          },
          "_temp_id": {
            "type": "string",
            "description": "Identificador temporal para destinatarios nuevos en solicitudes PUT (actualización integral) (por ejemplo, 'temp_1'). Úselo al crear destinatarios nuevos junto con destinatarios existentes en actualizaciones integrales. Debe comenzar con 'temp_' y ser único dentro de la solicitud. No se usa para solicitudes POST (creación); use el campo 'id' en su lugar."
          },
          "template_user_id": {
            "type": "string",
            "format": "uuid",
            "description": "Al crear desde una plantilla, el ID del usuario de plantilla a actualizar. Si se proporciona, los datos de este destinatario actualizarán al usuario de plantilla correspondiente. Si no se proporciona, se recurre a la coincidencia por orden. Solo se puede actualizar la información del usuario (nombre, email, teléfono, dirección, cargo, empresa) - el orden y la designación siempre se heredan de la plantilla."
          },
          "first_name": {
            "type": "string",
            "maxLength": 100,
            "description": "Nombre del destinatario"
          },
          "last_name": {
            "type": "string",
            "maxLength": 100,
            "description": "Apellido del destinatario (opcional, pero requerido si se usan las variables prellenadas full_name o last_name)"
          },
          "email": {
            "type": "string",
            "format": "email",
            "maxLength": 255,
            "description": "Dirección de email del destinatario"
          },
          "designation": {
            "type": "string",
            "enum": [
              "Signer",
              "Approver",
              "CC"
            ],
            "description": "Rol del destinatario. Signer firma el documento, Approver aprueba con campos de aprobación, CC recibe una copia al completarse."
          },
          "order": {
            "type": "integer",
            "minimum": 1,
            "description": "Número de secuencia de firma. Los destinatarios deben firmar en orden, firmando primero los números más bajos. Este campo es obligatorio para todos los destinatarios."
          },
          "phone_number": {
            "type": "string",
            "maxLength": 50,
            "nullable": true,
            "description": "Número de teléfono del destinatario"
          },
          "street_address": {
            "type": "string",
            "maxLength": 255,
            "nullable": true,
            "description": "Dirección postal"
          },
          "city": {
            "type": "string",
            "maxLength": 100,
            "nullable": true,
            "description": "Ciudad"
          },
          "state_province": {
            "type": "string",
            "maxLength": 100,
            "nullable": true,
            "description": "Estado o provincia"
          },
          "postal_code": {
            "type": "string",
            "maxLength": 20,
            "nullable": true,
            "description": "Código postal"
          },
          "country": {
            "type": "string",
            "maxLength": 100,
            "nullable": true,
            "description": "País"
          },
          "title": {
            "type": "string",
            "maxLength": 100,
            "nullable": true,
            "description": "Cargo"
          },
          "company": {
            "type": "string",
            "maxLength": 255,
            "nullable": true,
            "description": "Nombre de la empresa"
          },
          "custom_fields": {
            "type": "object",
            "additionalProperties": true,
            "description": "Pares clave-valor personalizados para datos adicionales del destinatario"
          }
        }
      },
      "Field": {
        "type": "object",
        "required": [
          "type",
          "position",
          "page_number"
        ],
        "description": "Definición de campo para solicitudes de firma. **Campos de solo lectura**: Establece read_only=true para prellenar un valor de campo que los firmantes no puedan editar. Usa read_only_value para texto estático, o prefilled_data para autocompletar a partir de los atributos del destinatario. **Fusión de campos basada en plantilla**: Al crear desde una plantilla con un array de fields, usa template_field_id (preferido) o variable_name (alternativa) para hacer coincidir los campos de la plantilla. Solo las propiedades proporcionadas sobrescriben los valores predeterminados de la plantilla (actualización parcial). Los campos sin coincidencia se ignoran.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identificador único (inclúyelo para actualizaciones, omítelo para campos nuevos)"
          },
          "template_field_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID del campo de plantilla a hacer coincidir para actualizaciones parciales (solo en creación basada en plantilla). Úsalo para identificar qué campo de la plantilla sobrescribir. Tiene prioridad sobre variable_name para la coincidencia."
          },
          "type": {
            "type": "string",
            "enum": [
              "signature",
              "text",
              "date",
              "checkbox",
              "dropdown",
              "initial",
              "initials",
              "text_area",
              "textarea",
              "image",
              "stamp",
              "approval_signature",
              "approval_checkmark",
              "approval_date"
            ],
            "description": "Tipo de campo. Acepta 'initial' o 'initials' (normalizado a 'initial'), 'textarea' o 'text_area' (normalizado a 'text_area')."
          },
          "position": {
            "type": "object",
            "required": [
              "x",
              "y",
              "width",
              "height"
            ],
            "description": "El campo debe caber dentro de los límites de la página: x + width <= 100 e y + height <= 100",
            "properties": {
              "x": {
                "type": "number",
                "minimum": 0,
                "maximum": 100,
                "description": "Coordenada X como porcentaje (0-100)"
              },
              "y": {
                "type": "number",
                "minimum": 0,
                "maximum": 100,
                "description": "Coordenada Y como porcentaje (0-100)"
              },
              "width": {
                "type": "number",
                "minimum": 0,
                "maximum": 100,
                "description": "Ancho como porcentaje (0-100). x + width debe ser <= 100"
              },
              "height": {
                "type": "number",
                "minimum": 0,
                "maximum": 100,
                "description": "Alto como porcentaje (0-100). y + height debe ser <= 100"
              }
            }
          },
          "page_number": {
            "type": "integer",
            "minimum": 1,
            "description": "Número de página donde se ubica el campo (indexado desde 1). No debe exceder el total de páginas del documento."
          },
          "required": {
            "type": "boolean",
            "default": false,
            "description": "Si el campo debe completarse"
          },
          "recipient_id": {
            "type": "string",
            "description": "ID del destinatario asignado a este campo. Usa un UUID real para creación o actualizaciones basadas en plantilla, o un ID temporal (por ejemplo, 'temp_1') para creación basada en documento, para referenciar destinatarios definidos en la misma solicitud."
          },
          "variable_name": {
            "type": "string",
            "maxLength": 100,
            "nullable": true,
            "description": "Nombre de variable para el campo (usado en plantillas). También se usa como alternativa para la coincidencia de campos en creación basada en plantilla cuando no se proporciona template_field_id."
          },
          "variable_defined_name": {
            "type": "string",
            "maxLength": 100,
            "nullable": true,
            "description": "Nombre de definición de campo personalizado, legible por humanos. Puede usarse como alternativa a variable_name para apuntar a campos en creación basada en plantilla."
          },
          "dropdown_options": {
            "description": "Opciones para campos desplegables",
            "oneOf": [
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              {
                "type": "object"
              }
            ]
          },
          "date_default": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Valor de fecha predeterminado"
          },
          "date_signing_default": {
            "type": "boolean",
            "default": false,
            "description": "Usar la fecha de firma como valor predeterminado"
          },
          "multi_group_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID de grupo para vincular varios campos de casilla de verificación o botón de opción entre sí. Los campos que comparten el mismo multi_group_id se comportan como un grupo mutuamente excluyente (como botones de opción) - seleccionar uno deselecciona automáticamente los demás del grupo. Usa el mismo UUID en varios campos para crear un grupo donde solo se pueda seleccionar una opción a la vez."
          },
          "format_rules": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/DateFormatRules"
              },
              {
                "$ref": "#/components/schemas/FileFormatRules"
              },
              {
                "type": "object",
                "additionalProperties": true
              }
            ],
            "nullable": true,
            "description": "Reglas de formato para el valor del campo. Para campos de fecha, usa el esquema DateFormatRules con la propiedad dateFormat. Para campos de archivo, usa el esquema FileFormatRules con la propiedad acceptedFileTypes (image_and_pdf, image, o pdf). Para campos url, usa { urlDisplayText: string }."
          },
          "validation_rules": {
            "$ref": "#/components/schemas/FieldValidationRules"
          },
          "read_only": {
            "type": "boolean",
            "default": false,
            "description": "Indica si este campo es de solo lectura (prellenado antes de la firma). Cuando es true, el firmante no puede editar el valor del campo. Útil para mostrar los términos del contrato, información del destinatario u otros datos fijos."
          },
          "read_only_value": {
            "type": "string",
            "nullable": true,
            "description": "Valor estático para campos de solo lectura. Tiene prioridad sobre prefilled_data si se especifican ambos. Solo aplicable cuando read_only es true. Ejemplo: 'Contrato #12345' o 'Acme Corporation'."
          },
          "prefilled_data": {
            "type": "string",
            "nullable": true,
            "enum": [
              "first_name",
              "last_name",
              "full_name",
              "email",
              "phone_number",
              "company",
              "title",
              "street_address",
              "city",
              "state_province",
              "postal_code",
              "country"
            ],
            "description": "Atributo del usuario para autocompletar cuando read_only es true. El valor se obtiene de los datos del destinatario asignado en el momento de la firma. También puede hacer referencia a las claves de custom_fields definidas en el destinatario (no se limita a los valores del enum). Solo aplicable cuando read_only es true y read_only_value no está configurado. Ejemplo: configúralo como 'email' para mostrar la dirección de correo electrónico del destinatario."
          },
          "required_conditions": {
            "$ref": "#/components/schemas/ConditionSet",
            "nullable": true,
            "description": "Reglas condicionales para cuándo este campo es obligatorio. Cuando se configura, tiene prioridad sobre el indicador estático 'required'. El campo solo es obligatorio cuando las condiciones se evalúan como verdaderas según los valores de otros campos."
          },
          "visibility_conditions": {
            "$ref": "#/components/schemas/ConditionSet",
            "nullable": true,
            "description": "Reglas condicionales para cuándo este campo es visible. Cuando se configura, el campo permanece oculto a menos que las condiciones se evalúen como verdaderas. Los campos ocultos no se validan al enviar."
          },
          "background_color": {
            "type": "string",
            "nullable": true,
            "pattern": "^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$",
            "description": "Color de fondo del campo como cadena de color hexadecimal (por ejemplo, '#FFFDE7', '#fff'). Útil para resaltar campos que necesitan atención.",
            "example": "#FFFDE7"
          }
        }
      },
      "AnchorTag": {
        "type": "object",
        "required": [
          "anchor_string",
          "type",
          "recipient_id"
        ],
        "description": "Definición de etiqueta de anclaje para la colocación automática de campos. Las etiquetas de anclaje son marcadores de texto incrustados en un documento PDF (por ejemplo, '{{SIGN_HERE}}') que se localizan automáticamente y se convierten en campos posicionados. El texto del anclaje se elimina del PDF después del procesamiento de forma predeterminada.",
        "properties": {
          "anchor_string": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200,
            "description": "Cadena de texto a buscar en el documento PDF. Los patrones comunes incluyen '{{SIGN_HERE}}', '{{DATE}}', etc.",
            "example": "{{SIGN_HERE}}"
          },
          "type": {
            "type": "string",
            "enum": [
              "signature",
              "initial",
              "initials",
              "text",
              "date",
              "checkbox",
              "radio_buttons",
              "radio",
              "dropdown",
              "textarea",
              "text_area",
              "url",
              "approval_signature",
              "approval_checkmark",
              "approval_date"
            ],
            "description": "Tipo de campo a colocar en la ubicación del anclaje"
          },
          "recipient_id": {
            "oneOf": [
              {
                "type": "integer"
              },
              {
                "type": "string"
              }
            ],
            "description": "ID del destinatario asignado a este campo. Usa un ID temporal (por ejemplo, 'temp_1') para la creación basada en documentos, o un número entero de orden para la basada en plantillas.",
            "example": "temp_1"
          },
          "x_offset": {
            "type": "number",
            "description": "Desplazamiento horizontal desde la posición del anclaje. Las unidades se determinan mediante offset_units (predeterminado: porcentaje del ancho de página).",
            "default": 0
          },
          "y_offset": {
            "type": "number",
            "description": "Desplazamiento vertical desde la posición del anclaje. Las unidades se determinan mediante offset_units (predeterminado: porcentaje del alto de página).",
            "default": 0
          },
          "offset_units": {
            "type": "string",
            "enum": [
              "percent",
              "pixels"
            ],
            "default": "percent",
            "description": "Tipo de unidad para x_offset y y_offset. 'percent' = porcentaje de las dimensiones de la página, 'pixels' = puntos PDF (72 DPI)."
          },
          "width": {
            "type": "number",
            "minimum": 0,
            "exclusiveMinimum": true,
            "description": "Ancho del campo como porcentaje del ancho de página. Los valores predeterminados varían según el tipo de campo (por ejemplo, signature=25, text=20, checkbox=3)."
          },
          "height": {
            "type": "number",
            "minimum": 0,
            "exclusiveMinimum": true,
            "description": "Alto del campo como porcentaje del alto de página. Los valores predeterminados varían según el tipo de campo (por ejemplo, signature=5, text=3, checkbox=3)."
          },
          "case_sensitive": {
            "type": "boolean",
            "default": false,
            "description": "Indica si la coincidencia de la cadena de anclaje distingue entre mayúsculas y minúsculas"
          },
          "match_whole_word": {
            "type": "boolean",
            "default": true,
            "description": "Indica si se deben coincidir solo palabras completas (delimitadas por caracteres que no son de palabra)"
          },
          "ignore_if_not_present": {
            "type": "boolean",
            "default": false,
            "description": "Si es true, omite este anclaje sin generar un error cuando no se encuentra en el documento. Si es false (predeterminado), un anclaje faltante provoca un error de validación."
          },
          "occurrence": {
            "type": "integer",
            "minimum": 0,
            "maximum": 1000,
            "default": 0,
            "description": "Qué ocurrencia usar para colocar un campo. 0 = todas las ocurrencias (predeterminado), 1 = solo la primera, 2 = solo la segunda, etc."
          },
          "remove_anchor_text": {
            "type": "boolean",
            "default": true,
            "description": "Indica si se debe eliminar el texto de anclaje del PDF dibujando un rectángulo blanco sobre él"
          },
          "required": {
            "type": "boolean",
            "default": true,
            "description": "Indica si el campo debe ser completado por el firmante"
          },
          "read_only": {
            "type": "boolean",
            "default": false,
            "description": "Indica si el campo es de solo lectura (prellenado)"
          },
          "read_only_value": {
            "type": "string",
            "nullable": true,
            "maxLength": 10000,
            "description": "Valor estático para campos de solo lectura"
          },
          "variable_name": {
            "type": "string",
            "nullable": true,
            "maxLength": 255,
            "description": "Nombre de variable para el campo"
          },
          "variable_defined_name": {
            "type": "string",
            "maxLength": 100,
            "nullable": true,
            "description": "Nombre legible de la definición de campo personalizado. Se puede usar como alternativa a variable_name para apuntar a campos en la creación basada en plantillas."
          },
          "background_color": {
            "type": "string",
            "nullable": true,
            "pattern": "^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$",
            "description": "Color de fondo en hexadecimal (por ejemplo, '#FFFDE7')",
            "example": "#FFFDE7"
          },
          "dropdown_options": {
            "description": "Opciones para campos desplegables",
            "oneOf": [
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              {
                "type": "object"
              }
            ]
          },
          "date_default": {
            "type": "string",
            "nullable": true,
            "maxLength": 50,
            "description": "Valor de fecha predeterminado"
          },
          "date_signing_default": {
            "type": "boolean",
            "default": false,
            "description": "Usar la fecha de firma como valor predeterminado"
          },
          "multi_group_id": {
            "type": "string",
            "nullable": true,
            "maxLength": 255,
            "description": "ID de grupo para vincular campos de casilla de verificación/radio"
          }
        }
      },
      "ConditionSet": {
        "type": "object",
        "required": [
          "logic",
          "groups"
        ],
        "description": "Un conjunto de grupos de condiciones con lógica anidada. El operador 'logic' externo combina los grupos, mientras que las condiciones de cada grupo usan el operador opuesto. Ejemplo: logic='and' significa que todos los grupos deben coincidir, y dentro de cada grupo cualquier condición puede coincidir (OR).",
        "properties": {
          "logic": {
            "type": "string",
            "enum": [
              "and",
              "or"
            ],
            "description": "Operador lógico para combinar grupos. 'and' = todos los grupos deben coincidir, 'or' = cualquier grupo puede coincidir."
          },
          "groups": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ConditionGroup"
            },
            "description": "Array de grupos de condiciones"
          }
        }
      },
      "ConditionGroup": {
        "type": "object",
        "required": [
          "conditions"
        ],
        "properties": {
          "conditions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Condition"
            },
            "description": "Array de condiciones dentro de este grupo. Se combinan usando el operador opuesto al del ConditionSet padre."
          }
        }
      },
      "Condition": {
        "type": "object",
        "required": [
          "field_id",
          "operator"
        ],
        "description": "Una sola condición que evalúa el valor de un campo.",
        "properties": {
          "field_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID del campo a evaluar"
          },
          "operator": {
            "type": "string",
            "enum": [
              "is_filled",
              "is_empty",
              "equals",
              "not_equals",
              "contains",
              "not_contains",
              "greater_than",
              "less_than",
              "greater_than_or_equal",
              "less_than_or_equal"
            ],
            "description": "Operador de comparación. 'is_filled'/'is_empty' no requieren un valor. Operadores de texto: equals, not_equals, contains, not_contains. Operadores numéricos/de fecha: greater_than, less_than, greater_than_or_equal, less_than_or_equal."
          },
          "value": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "number"
              }
            ],
            "nullable": true,
            "description": "Valor con el que comparar. No es necesario para los operadores is_filled/is_empty."
          }
        }
      },
      "SigningRequestReminder": {
        "type": "object",
        "required": [
          "hours",
          "subject",
          "message"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identificador único (inclúyelo para actualizaciones, omítelo para recordatorios nuevos)"
          },
          "hours": {
            "type": "integer",
            "minimum": 1,
            "description": "Horas antes de la expiración para enviar el recordatorio"
          },
          "all_users": {
            "type": "boolean",
            "default": false,
            "description": "Enviar recordatorio a todos los destinatarios"
          },
          "recipient_id": {
            "type": "string",
            "nullable": true,
            "description": "ID de destinatario específico (obligatorio si all_users es false). Usa un UUID real para destinatarios existentes o un ID temporal (por ejemplo, 'temp_1') para creación basada en documento, para referenciar destinatarios dentro de la misma solicitud."
          },
          "subject": {
            "type": "string",
            "maxLength": 255,
            "description": "Asunto del email"
          },
          "message": {
            "type": "string",
            "maxLength": 5000,
            "description": "Cuerpo del mensaje del email"
          }
        }
      },
      "DeletedRecipient": {
        "type": "object",
        "required": [
          "recipient_id",
          "field_action"
        ],
        "properties": {
          "recipient_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID del destinatario a eliminar"
          },
          "field_action": {
            "type": "string",
            "enum": [
              "delete",
              "reassign"
            ],
            "description": "Acción a realizar con los campos asignados a este destinatario"
          },
          "reassign_to_recipient_id": {
            "type": "string",
            "format": "uuid",
            "description": "Destinatario al que reasignar los campos (obligatorio si field_action es 'reassign')"
          }
        }
      },
      "SigningRequestUser": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identificador único del usuario de la solicitud de firma"
          },
          "name": {
            "type": "string",
            "description": "Nombre del destinatario (nombre y apellido combinados)"
          },
          "email": {
            "type": "string",
            "format": "email",
            "description": "Dirección de email del destinatario"
          },
          "first_name": {
            "type": "string",
            "nullable": true,
            "description": "Nombre del destinatario"
          },
          "last_name": {
            "type": "string",
            "nullable": true,
            "description": "Apellido del destinatario"
          },
          "designation": {
            "type": "string",
            "enum": [
              "Signer",
              "Approver",
              "CC"
            ],
            "description": "Rol del destinatario. El Firmante firma el documento, el Aprobador aprueba con campos de aprobación, CC recibe una copia al completarse."
          },
          "order": {
            "type": "integer",
            "minimum": 1,
            "description": "Orden de firma"
          },
          "finished_on": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Marca de tiempo de cuándo este destinatario completó todas las acciones"
          },
          "declined_on": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Marca de tiempo de cuándo este destinatario rechazó firmar"
          },
          "decline_reason": {
            "type": "string",
            "nullable": true,
            "description": "Motivo proporcionado por el destinatario para el rechazo"
          },
          "phone_number": {
            "type": "string",
            "nullable": true,
            "description": "Número de teléfono del destinatario"
          },
          "street_address": {
            "type": "string",
            "nullable": true,
            "description": "Dirección postal del destinatario"
          },
          "city": {
            "type": "string",
            "nullable": true,
            "description": "Ciudad del destinatario"
          },
          "state_province": {
            "type": "string",
            "nullable": true,
            "description": "Estado o provincia del destinatario"
          },
          "postal_code": {
            "type": "string",
            "nullable": true,
            "description": "Código postal del destinatario"
          },
          "country": {
            "type": "string",
            "nullable": true,
            "description": "País del destinatario"
          },
          "title": {
            "type": "string",
            "nullable": true,
            "description": "Cargo del destinatario"
          },
          "company": {
            "type": "string",
            "nullable": true,
            "description": "Nombre de la empresa del destinatario"
          },
          "custom_fields": {
            "type": "object",
            "nullable": true,
            "description": "Valores de campos personalizados para este destinatario"
          },
          "required_fields": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Lista de campos de datos del destinatario requeridos para el envío (según los campos con asignaciones de variable_name). Siempre incluye 'email' y 'first_name'."
          },
          "missing_fields": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Lista de campos requeridos que actualmente están vacíos para este destinatario"
          },
          "required_read_only_fields": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "variable_name": {
                  "type": "string",
                  "nullable": true,
                  "description": "Nombre de variable del campo de solo lectura"
                },
                "variable_defined_name": {
                  "type": "string",
                  "nullable": true,
                  "description": "Nombre de campo legible por humanos proveniente de la definición del campo personalizado (por ejemplo, 'artist_name'). Solo está presente para campos vinculados a una definición de campo personalizado; en caso contrario es null."
                },
                "field_type": {
                  "type": "string",
                  "description": "Tipo del campo (text, date, etc.)"
                },
                "has_value": {
                  "type": "boolean",
                  "description": "Indica si este campo de solo lectura tiene un valor establecido"
                }
              }
            },
            "description": "Lista de campos de solo lectura requeridos que necesitan valores pre-rellenados antes del envío"
          },
          "ready_to_send": {
            "type": "boolean",
            "description": "Indica si este destinatario tiene todos los datos requeridos completados para el envío"
          }
        },
        "required": [
          "id",
          "first_name",
          "email",
          "designation",
          "order"
        ]
      },
      "SigningRequestField": {
        "type": "object",
        "description": "Campo asociado a una solicitud de firma, que contiene información de posición, tipo y valor",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identificador único del campo"
          },
          "type": {
            "type": "string",
            "enum": [
              "text",
              "signature",
              "date",
              "checkbox",
              "initial",
              "dropdown",
              "radio_buttons",
              "text_area",
              "url",
              "file",
              "stamp",
              "approval_signature",
              "approval_checkmark",
              "approval_date"
            ],
            "description": "Tipo del campo. Alias limpio de field_type."
          },
          "recipient_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID del destinatario asignado a este campo. Alias limpio de companies_workspaces_signing_requests_users_id."
          },
          "value": {
            "type": "string",
            "nullable": true,
            "description": "Valor final firmado del campo. Alias limpio de final_value."
          },
          "position": {
            "type": "object",
            "description": "Posición y dimensiones del campo en el documento. Todos los valores son porcentajes (0-100).",
            "properties": {
              "x": {
                "type": "number",
                "nullable": true,
                "description": "Posición X (porcentaje, 0-100). Alias limpio de x_postion."
              },
              "y": {
                "type": "number",
                "nullable": true,
                "description": "Posición Y (porcentaje, 0-100). Alias limpio de y_position."
              },
              "width": {
                "type": "number",
                "nullable": true,
                "description": "Ancho (porcentaje, 0-100)."
              },
              "height": {
                "type": "number",
                "nullable": true,
                "description": "Alto (porcentaje, 0-100). Alias limpio de heigh."
              }
            }
          },
          "companies_workspaces_signing_requests_id": {
            "type": "string",
            "format": "uuid",
            "description": "Obsoleto: redundante con el parámetro de ruta. ID de la solicitud de firma a la que pertenece este campo."
          },
          "companies_workspaces_signing_requests_users_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "Obsoleto: usa 'recipient_id' en su lugar. ID del destinatario asignado a este campo."
          },
          "field_type": {
            "type": "string",
            "enum": [
              "text",
              "signature",
              "date",
              "checkbox",
              "initial",
              "dropdown",
              "radio_buttons",
              "text_area",
              "url",
              "file",
              "stamp",
              "approval_signature",
              "approval_checkmark",
              "approval_date"
            ],
            "description": "Obsoleto: usa 'type' en su lugar. Tipo del campo."
          },
          "required": {
            "type": "boolean",
            "description": "Indica si el campo es obligatorio."
          },
          "x_postion": {
            "type": "number",
            "nullable": true,
            "description": "Obsoleto: usa 'position.x' en su lugar. Posición X (nota: el nombre de la columna tiene un error tipográfico)."
          },
          "y_position": {
            "type": "number",
            "nullable": true,
            "description": "Obsoleto: usa 'position.y' en su lugar. Posición Y del campo."
          },
          "width": {
            "type": "number",
            "nullable": true,
            "description": "Obsoleto: usa 'position.width' en su lugar. Ancho del campo."
          },
          "heigh": {
            "type": "number",
            "nullable": true,
            "description": "Obsoleto: usa 'position.height' en su lugar. Altura (nota: el nombre de la columna tiene un error tipográfico)."
          },
          "page_number": {
            "type": "integer",
            "nullable": true,
            "description": "Número de página donde se encuentra el campo (indexado desde 1)"
          },
          "tl_position": {
            "type": "number",
            "nullable": true,
            "description": "Posición de la esquina superior izquierda"
          },
          "tr_position": {
            "type": "number",
            "nullable": true,
            "description": "Posición de la esquina superior derecha"
          },
          "bl_position": {
            "type": "number",
            "nullable": true,
            "description": "Posición de la esquina inferior izquierda"
          },
          "br_position": {
            "type": "number",
            "nullable": true,
            "description": "Posición de la esquina inferior derecha"
          },
          "variable_name": {
            "type": "string",
            "nullable": true,
            "description": "Nombre de variable para el mapeo de datos prellenados"
          },
          "variable_defined_name": {
            "type": "string",
            "nullable": true,
            "description": "Nombre de campo legible por humanos proveniente de la definición del campo personalizado (por ejemplo, 'artist_name'). Solo está presente en campos vinculados a una definición de campo personalizado; de lo contrario es null."
          },
          "final_value": {
            "type": "string",
            "nullable": true,
            "description": "Obsoleto: usa 'value' en su lugar. Valor final firmado del campo."
          },
          "date_default": {
            "type": "string",
            "nullable": true,
            "description": "Valor de fecha predeterminado"
          },
          "date_signing_default": {
            "type": "boolean",
            "nullable": true,
            "description": "Si se debe usar la fecha de firma como valor predeterminado."
          },
          "format_rules": {
            "type": "object",
            "nullable": true,
            "description": "Reglas de formato (por ejemplo, formato de fecha)"
          },
          "validation_rules": {
            "type": "object",
            "nullable": true,
            "description": "Reglas de validación para el campo"
          },
          "dropdown_options": {
            "nullable": true,
            "description": "Opciones para campos desplegables",
            "oneOf": [
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              {
                "type": "object"
              }
            ]
          },
          "multi_group_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID de grupo para vincular varios campos de casilla de verificación o botón de opción entre sí. Los campos que comparten el mismo multi_group_id se comportan como un grupo mutuamente excluyente (como botones de opción); seleccionar uno deselecciona automáticamente los demás del grupo. Usa el mismo UUID en varios campos para crear un grupo donde solo se pueda seleccionar una opción a la vez."
          },
          "read_only": {
            "type": "boolean",
            "description": "Si el campo es de solo lectura."
          },
          "read_only_value": {
            "type": "string",
            "nullable": true,
            "description": "Valor estático para campos de solo lectura"
          },
          "background_color": {
            "type": "string",
            "nullable": true,
            "description": "Color de fondo en hexadecimal (por ejemplo, '#FFFDE7')"
          },
          "calculated_font_size": {
            "type": "number",
            "nullable": true,
            "description": "Tamaño de fuente calculado para el campo"
          },
          "deleted": {
            "type": "integer",
            "enum": [
              0,
              1
            ],
            "description": "Obsoleto: campo interno, se eliminará en v2. Indicador de eliminación lógica (0 = activo, 1 = eliminado)."
          }
        },
        "required": [
          "id",
          "field_type",
          "page_number"
        ]
      },
      "SendSigningRequestResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "description": "Si la Solicitud de Firma se envió correctamente"
          },
          "message": {
            "type": "string",
            "description": "Mensaje de éxito"
          },
          "sentTo": {
            "type": "string",
            "format": "email",
            "description": "Dirección de correo electrónico a la que se envió la Solicitud de Firma"
          },
          "sentAt": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de cuando se envió la solicitud"
          }
        }
      },
      "Webhook": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identificador único del Webhook"
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "URL del Webhook"
          },
          "description": {
            "type": "string",
            "nullable": true,
            "description": "Descripción del Webhook"
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Eventos que activan este Webhook"
          },
          "enabled": {
            "type": "boolean",
            "description": "Si el Webhook está habilitado"
          },
          "consecutive_failures": {
            "type": "integer",
            "description": "Número de fallos de entrega consecutivos"
          },
          "auto_disabled_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Marca de tiempo de cuando el Webhook se deshabilitó automáticamente debido a fallos"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de creación del Webhook"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de la última actualización del Webhook"
          }
        },
        "required": [
          "id",
          "url",
          "events",
          "enabled",
          "created_at"
        ]
      },
      "PatchSigningRequestBodySchema": {
        "oneOf": [
          {
            "type": "object",
            "required": [
              "document"
            ],
            "description": "Crear una Solicitud de Firma a partir de un documento PDF",
            "properties": {
              "document": {
                "type": "string",
                "format": "byte",
                "description": "Documento PDF o DOCX codificado en base64. Los archivos DOCX se convierten automáticamente a PDF. El número de páginas se extraerá automáticamente."
              },
              "name": {
                "type": "string",
                "maxLength": 255,
                "description": "Nombre para la Solicitud de Firma"
              },
              "description": {
                "type": "string",
                "description": "Descripción para la Solicitud de Firma"
              },
              "expiration_hours": {
                "type": "integer",
                "minimum": 1,
                "default": 168,
                "description": "Horas hasta que expire la Solicitud de Firma (predeterminado: 168 = 7 días)"
              },
              "recipients": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Recipient"
                },
                "description": "Destinatarios para la Solicitud de Firma. Usa IDs temporales (por ejemplo, 'temp_1') en el campo id para hacer referencia a los destinatarios en fields/reminders."
              },
              "fields": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Field"
                },
                "description": "Campos para colocar en el documento. Usa recipient_id para asignar campos a los destinatarios."
              },
              "anchor_tags": {
                "type": "array",
                "maxItems": 100,
                "items": {
                  "$ref": "#/components/schemas/AnchorTag"
                },
                "description": "Etiquetas de anclaje para la colocación automática de campos. Se localizan marcadores de texto en el PDF y se convierten en campos posicionados. El texto de anclaje se elimina del PDF después del procesamiento. Los campos creados a partir de etiquetas de anclaje se añaden junto con cualquier campo especificado manualmente. Solo está disponible para la creación basada en documento (no basada en Plantilla)."
              },
              "reminders": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/SigningRequestReminder"
                },
                "description": "Recordatorios para enviar a los destinatarios"
              },
              "settings": {
                "$ref": "#/components/schemas/SigningRequestSettings",
                "description": "Configuración de la Solicitud de Firma"
              }
            }
          },
          {
            "type": "object",
            "required": [
              "template_id"
            ],
            "description": "Crear una Solicitud de Firma a partir de una Plantilla. Admite actualizaciones parciales tanto para destinatarios como para campos.",
            "properties": {
              "template_id": {
                "type": "string",
                "format": "uuid",
                "description": "ID de la Plantilla a partir de la cual crear la Solicitud de Firma. El documento, los campos y los destinatarios predeterminados se copiarán de la Plantilla."
              },
              "name": {
                "type": "string",
                "maxLength": 255,
                "description": "Nombre personalizado para la Solicitud de Firma (usa el nombre de la Plantilla de forma predeterminada si no se proporciona)"
              },
              "description": {
                "type": "string",
                "description": "Descripción personalizada (usa la descripción de la Plantilla de forma predeterminada si no se proporciona)"
              },
              "expiration_hours": {
                "type": "integer",
                "minimum": 1,
                "description": "Sobrescribir las horas de expiración de la Plantilla"
              },
              "recipients": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Recipient"
                },
                "description": "Sobrescrituras de destinatarios opcionales. Usa template_user_id (preferido) u order (alternativa) para hacer coincidir con los usuarios de la Plantilla. Solo se puede actualizar la información del usuario (first_name, last_name, email, phone_number, campos de dirección, title, company); order y designation siempre se heredan de la Plantilla. Los destinatarios no proporcionados usarán los valores predeterminados de la Plantilla."
              },
              "fields": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Field"
                },
                "description": "Sobrescrituras opcionales de campos para actualizaciones parciales. Usa template_field_id (preferido) o variable_name (alternativa) para identificar los campos de la plantilla. Solo las propiedades proporcionadas sobrescriben los valores predeterminados de la plantilla. Propiedades de sobrescritura admitidas: type, required, position, read_only, read_only_value, format_rules, validation_rules, dropdown_options, date_default, date_signing_default, multi_group_id. Los campos que no coincidan se ignoran. Si se omite el array fields, se usan todos los campos de la plantilla tal cual."
              },
              "settings": {
                "$ref": "#/components/schemas/SigningRequestSettings",
                "description": "Sobrescribe la configuración de la plantilla"
              }
            },
            "example": {
              "template_id": "21424147-11c0-43d5-ac5f-a1f7001b5607",
              "name": "Contract for Client X",
              "recipients": [
                {
                  "template_user_id": "template-user-uuid-1",
                  "first_name": "Toni",
                  "last_name": "Campins",
                  "email": "acampins@cocodin.com"
                }
              ],
              "fields": [
                {
                  "template_field_id": "field-uuid-1",
                  "read_only": true,
                  "read_only_value": "Contract #12345"
                },
                {
                  "variable_name": "company_name",
                  "read_only_value": "Acme Corporation"
                }
              ]
            }
          }
        ]
      },
      "UpdateSigningRequestBodySchema": {
        "type": "object",
        "properties": {
          "signing_request_properties": {
            "type": "object",
            "description": "Actualiza las propiedades de la solicitud de firma",
            "properties": {
              "name": {
                "type": "string",
                "maxLength": 255
              },
              "description": {
                "type": "string"
              },
              "document": {
                "type": "string",
                "format": "byte",
                "description": "Reemplaza el documento (PDF codificado en base64)"
              },
              "expiration_hours": {
                "type": "integer",
                "minimum": 1
              },
              "settings": {
                "$ref": "#/components/schemas/SigningRequestSettings"
              }
            }
          },
          "recipients": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Recipient"
            },
            "description": "Inserta o actualiza destinatarios: incluye 'id' para actualizar destinatarios existentes, usa '_temp_id' (por ejemplo, 'temp_1') para destinatarios nuevos y así poder referenciarlos en fields y reminders dentro de la misma solicitud"
          },
          "deleted_recipients": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DeletedRecipient"
            },
            "description": "Destinatarios a eliminar y cómo manejar sus campos"
          },
          "force_remove_conditions": {
            "type": "boolean",
            "default": false,
            "description": "Al eliminar destinatarios cuyos campos son referenciados por condiciones en otros campos: si es true, se eliminan automáticamente las referencias de la condición; si es false (predeterminado), la solicitud se rechazará con un error que lista los campos dependientes."
          },
          "fields": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Field"
            },
            "description": "Inserta o actualiza campos: incluye id para actualizar, omite id para crear uno nuevo"
          },
          "reminders": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SigningRequestReminder"
            },
            "description": "Inserta o actualiza recordatorios: incluye id para actualizar, omite id para crear uno nuevo"
          }
        }
      },
      "GenerateJWTRequest": {
        "type": "object",
        "required": [
          "companies_workspaces_templates_id"
        ],
        "properties": {
          "companies_workspaces_templates_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID de la plantilla para la que se generará el JWT"
          }
        }
      },
      "GenerateJWTResponse": {
        "type": "object",
        "properties": {
          "token": {
            "type": "string",
            "description": "El token JWT generado"
          },
          "jwt_record_id": {
            "type": "string",
            "format": "uuid",
            "description": "Identificador único de este registro JWT"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de expiración del JWT (30 días desde su creación)"
          }
        },
        "required": [
          "token",
          "expires_at"
        ]
      },
      "RevokeJWTRequest": {
        "type": "object",
        "required": [
          "jwt_id"
        ],
        "properties": {
          "jwt_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID del token JWT a revocar"
          }
        }
      },
      "RevokeJWTResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "description": "Mensaje de confirmación"
          },
          "jwt_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID del JWT revocado"
          },
          "revoked": {
            "type": "boolean",
            "description": "Indica si el JWT se revocó correctamente"
          }
        },
        "required": [
          "message"
        ]
      },
      "GenerateSigningRequestJWTRequest": {
        "type": "object",
        "required": [
          "companies_workspaces_signing_requests_id"
        ],
        "properties": {
          "companies_workspaces_signing_requests_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID de la solicitud de firma para la que se generará el JWT"
          }
        }
      },
      "GenerateSigningRequestJWTResponse": {
        "type": "object",
        "properties": {
          "jwt": {
            "type": "string",
            "description": "El token JWT generado"
          },
          "jwt_id": {
            "type": "string",
            "format": "uuid",
            "description": "Identificador único de este JWT"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de expiración del JWT (7 días desde su creación)"
          },
          "signing_request_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID de la solicitud de firma a la que corresponde este JWT"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de cuándo se creó el JWT"
          }
        },
        "required": [
          "jwt",
          "expires_at",
          "signing_request_id"
        ]
      },
      "RevokeSigningRequestJWTRequest": {
        "type": "object",
        "required": [
          "jwt_id"
        ],
        "properties": {
          "jwt_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID del token JWT a revocar"
          }
        }
      },
      "RevokeSigningRequestJWTResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "description": "Mensaje de confirmación"
          },
          "jwt_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID del JWT revocado"
          },
          "revoked": {
            "type": "boolean",
            "description": "Indica si el JWT se revocó correctamente"
          }
        },
        "required": [
          "message"
        ]
      },
      "ColorPalette": {
        "type": "object",
        "description": "Paleta de colores resuelta para la experiencia de firma. Todos los valores son cadenas de color hexadecimal (#rrggbb).",
        "properties": {
          "primary": {
            "type": "string",
            "description": "Color de acción principal (botones, enlaces, acentos)",
            "example": "#2563eb"
          },
          "primary_fg": {
            "type": "string",
            "description": "Color de texto sobre elementos con el color primario",
            "example": "#ffffff"
          },
          "background": {
            "type": "string",
            "description": "Color de fondo de la página/lienzo",
            "example": "#1c1c21"
          },
          "foreground": {
            "type": "string",
            "description": "Color de texto principal",
            "example": "#ffffff"
          },
          "card": {
            "type": "string",
            "description": "Color de fondo de tarjetas/paneles",
            "example": "#22222a"
          },
          "border": {
            "type": "string",
            "description": "Color de bordes y separadores",
            "example": "#3b3b3b"
          },
          "accent": {
            "type": "string",
            "description": "Acento de la interfaz del editor",
            "example": "#34eeff"
          },
          "accent_fg": {
            "type": "string",
            "description": "Color de primer plano sobre el acento",
            "example": "#000000"
          },
          "canvas": {
            "type": "string",
            "description": "Entorno del lienzo de documento del editor",
            "example": "#0f1419"
          },
          "muted": {
            "type": "string",
            "description": "Superficie atenuada (por defecto usa el card resuelto)",
            "example": "#22222a"
          },
          "muted_fg": {
            "type": "string",
            "description": "Texto atenuado (se calcula para mantener la legibilidad cuando no está definido)",
            "example": "#b8b8b8"
          }
        }
      },
      "CompanySettings": {
        "type": "object",
        "properties": {
          "default_expiration_hours": {
            "type": "integer",
            "minimum": 1
          },
          "require_terms_acceptance": {
            "type": "boolean"
          },
          "show_custom_branding_only": {
            "type": "boolean"
          },
          "require_otp_verification": {
            "type": "boolean"
          },
          "allow_presigning_download": {
            "type": "boolean"
          },
          "disable_guided_navigation": {
            "type": "boolean"
          },
          "show_signature_frame": {
            "type": "boolean"
          },
          "show_partial_watermark": {
            "type": "boolean"
          },
          "email_local_part": {
            "type": "string"
          },
          "color_primary": {
            "type": "string",
            "nullable": true
          },
          "color_primary_fg": {
            "type": "string",
            "nullable": true
          },
          "color_background": {
            "type": "string",
            "nullable": true
          },
          "color_foreground": {
            "type": "string",
            "nullable": true
          },
          "color_card": {
            "type": "string",
            "nullable": true
          },
          "color_border": {
            "type": "string",
            "nullable": true
          },
          "color_accent": {
            "type": "string",
            "nullable": true
          },
          "color_accent_fg": {
            "type": "string",
            "nullable": true
          },
          "color_canvas": {
            "type": "string",
            "nullable": true
          },
          "color_muted": {
            "type": "string",
            "nullable": true
          },
          "color_muted_fg": {
            "type": "string",
            "nullable": true
          },
          "show_qr_code": {
            "type": "boolean",
            "nullable": true,
            "description": "Muestra un código QR en la página de firma que permite a los firmantes continuar desde su teléfono. Este es el valor predeterminado a nivel de empresa; los espacios de trabajo, plantillas y solicitudes de firma pueden sobrescribirlo."
          }
        },
        "required": [
          "default_expiration_hours"
        ]
      },
      "WorkspaceSettings": {
        "type": "object",
        "properties": {
          "workspace_id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "description": "Nombre del espacio de trabajo"
          },
          "team_email": {
            "type": "string",
            "format": "email",
            "description": "Correo electrónico de contacto del espacio de trabajo"
          },
          "timezone": {
            "type": "string",
            "description": "Zona horaria del espacio de trabajo"
          },
          "language": {
            "type": "string",
            "description": "Idioma del espacio de trabajo para las plantillas de correo electrónico",
            "enum": [
              "en",
              "es",
              "it",
              "pt",
              "fr",
              "de",
              "el",
              "ru",
              "pl"
            ],
            "default": "en"
          },
          "signing_request_email_header": {
            "type": "string",
            "description": "Texto de encabezado de correo electrónico personalizado"
          },
          "signing_request_email_body": {
            "type": "string",
            "description": "Cuerpo de correo electrónico HTML personalizado"
          },
          "show_credit_cost_in_editor": {
            "type": "boolean",
            "description": "Indica si se debe mostrar el costo en créditos en los editores incrustados de plantillas y solicitudes de firma",
            "default": true
          },
          "require_otp_verification": {
            "type": "boolean",
            "nullable": true,
            "description": "Indica si los firmantes deben verificar su correo electrónico mediante OTP antes de acceder a los documentos. null = heredar de la configuración de la empresa, true = requerir OTP, false = no requerir OTP"
          },
          "require_terms_acceptance": {
            "type": "boolean",
            "nullable": true,
            "description": "Indica si los firmantes deben aceptar los términos antes de firmar. null hereda la configuración a nivel de empresa."
          },
          "disable_guided_navigation": {
            "type": "boolean",
            "nullable": true,
            "description": "Desactiva el desplazamiento automático hacia el siguiente campo requerido durante la firma. Hereda del espacio de trabajo o de la empresa si no está definido."
          },
          "show_signature_frame": {
            "type": "boolean",
            "nullable": true,
            "description": "Indica si se debe mostrar un marco visual con el ID de Firma alrededor de las firmas en los PDF completados. null = heredar de la configuración de la empresa (habilitado por defecto), true = mostrar marco, false = ocultar marco"
          },
          "allow_presigning_download": {
            "type": "boolean",
            "nullable": true,
            "description": "Permite a los firmantes descargar el documento original antes de firmar. null hereda la configuración a nivel de empresa."
          },
          "show_partial_watermark": {
            "type": "boolean",
            "nullable": true,
            "description": "Muestra una marca de agua de EN PROGRESO en las descargas parciales del PDF cuando no todos los firmantes han completado el proceso. null hereda la configuración a nivel de empresa."
          },
          "show_qr_code": {
            "type": "boolean",
            "nullable": true,
            "description": "Muestra un código QR en la página de firma que permite a los firmantes continuar desde su teléfono. null hereda la configuración a nivel de empresa."
          },
          "color_primary": {
            "type": "string",
            "nullable": true,
            "description": "Anulación del color primario (hex #rrggbb). Null para heredar de la empresa.",
            "example": "#2563eb"
          },
          "color_primary_fg": {
            "type": "string",
            "nullable": true,
            "description": "Anulación del color primario de primer plano. Null para heredar.",
            "example": "#ffffff"
          },
          "color_background": {
            "type": "string",
            "nullable": true,
            "description": "Anulación del color de fondo. Null para heredar.",
            "example": "#0f172a"
          },
          "color_foreground": {
            "type": "string",
            "nullable": true,
            "description": "Anulación del color de primer plano/texto. Null para heredar.",
            "example": "#ffffff"
          },
          "color_card": {
            "type": "string",
            "nullable": true,
            "description": "Anulación del color de fondo de las tarjetas. Null para heredar.",
            "example": "#22222a"
          },
          "color_border": {
            "type": "string",
            "nullable": true,
            "description": "Anulación del color del borde. Null para heredar.",
            "example": "#3b3b3b"
          },
          "color_accent": {
            "type": "string",
            "nullable": true,
            "description": "Color de acento de la interfaz del editor. Null para heredar.",
            "example": "#34eeff"
          },
          "color_accent_fg": {
            "type": "string",
            "nullable": true,
            "description": "Color de primer plano en superficies de acento. Null para heredar.",
            "example": "#000000"
          },
          "color_canvas": {
            "type": "string",
            "nullable": true,
            "description": "Color del entorno del lienzo de documento del editor. Null para heredar.",
            "example": "#0f1419"
          },
          "color_muted": {
            "type": "string",
            "nullable": true,
            "description": "Color de superficie atenuado. Null para heredar.",
            "example": "#22222a"
          },
          "color_muted_fg": {
            "type": "string",
            "nullable": true,
            "description": "Color de texto atenuado. Null para heredar.",
            "example": "#b8b8b8"
          },
          "email_local_part": {
            "type": "string",
            "nullable": true,
            "description": "La parte local (antes de la @) de la dirección de correo del remitente. Null para heredar de la configuración de la empresa. Solo aplica cuando hay un dominio personalizado verificado configurado.",
            "example": "signatures",
            "pattern": "^[a-z0-9]([a-z0-9._-]*[a-z0-9])?$",
            "minLength": 1,
            "maxLength": 64
          },
          "signing_button_label_overrides": {
            "type": "object",
            "nullable": true,
            "description": "Etiquetas de botón personalizadas por idioma para la vista de firma. Las claves son códigos de idioma (en, de, etc.); los valores son objetos que asignan claves de traducción a texto personalizado. Null para usar los valores predeterminados.",
            "additionalProperties": {
              "type": "object",
              "additionalProperties": {
                "type": "string"
              }
            }
          }
        },
        "required": [
          "workspace_id"
        ]
      },
      "WorkspaceCustomField": {
        "type": "object",
        "description": "Una definición de campo personalizado para un Espacio de Trabajo",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identificador único"
          },
          "field_name": {
            "type": "string",
            "description": "Nombre de campo legible por máquina (generado automáticamente a partir de la etiqueta)"
          },
          "field_label": {
            "type": "string",
            "description": "Etiqueta de visualización legible para humanos"
          },
          "is_preset": {
            "type": "boolean",
            "description": "Si es true, este campo tiene un valor preestablecido para todos los usuarios"
          },
          "preset_value": {
            "type": "string",
            "nullable": true,
            "description": "Valor preestablecido (solo se usa cuando is_preset=true)"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "field_name",
          "field_label"
        ]
      },
      "TemplateCustomField": {
        "type": "object",
        "description": "Una definición de campo personalizado para una Plantilla",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identificador único"
          },
          "field_name": {
            "type": "string",
            "description": "Nombre de campo legible por máquina"
          },
          "field_label": {
            "type": "string",
            "description": "Etiqueta de visualización legible para humanos"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "field_name"
        ]
      },
      "SigningRequestCustomField": {
        "type": "object",
        "description": "Una definición de campo personalizado para una Solicitud de Firma",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identificador único"
          },
          "field_name": {
            "type": "string",
            "description": "Nombre de campo legible por máquina"
          },
          "field_label": {
            "type": "string",
            "description": "Etiqueta de visualización legible para humanos"
          },
          "copied_from_template": {
            "type": "boolean",
            "description": "True si este campo se copió de una Plantilla"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "field_name"
        ]
      },
      "Domain": {
        "type": "object",
        "description": "Configuración de dominio de correo para enviar correos de Solicitud de Firma",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identificador único del dominio"
          },
          "domain": {
            "type": "string",
            "description": "El nombre de dominio (por ejemplo, 'example.com')"
          },
          "verification_status": {
            "type": "integer",
            "enum": [
              0,
              1,
              2
            ],
            "description": "Estado de verificación de propiedad del dominio: 0=pendiente, 1=propiedad verificada (registro TXT confirmado), 2=finalizado (registrado con el proveedor de correo)"
          },
          "domain_status": {
            "type": "integer",
            "enum": [
              0,
              1
            ],
            "description": "Estado de envío de correo: 0=registros DNS pendientes de verificación, 1=totalmente verificado y listo para enviar"
          },
          "is_primary": {
            "type": "boolean",
            "description": "Si este es el dominio primario para enviar correos desde este Espacio de Trabajo"
          },
          "verification_token": {
            "type": "string",
            "description": "Token para agregar como registro TXT para la verificación de propiedad del dominio. Solo se devuelve cuando verification_status=0."
          },
          "resend_domain_id": {
            "type": "string",
            "nullable": true,
            "description": "ID de dominio del proveedor de correo externo (uso interno)"
          },
          "dns_records": {
            "type": "array",
            "nullable": true,
            "description": "Registros DNS requeridos para el envío de correo. Solo se devuelven después de la finalización del dominio (verification_status=2).",
            "items": {
              "$ref": "#/components/schemas/DomainDnsRecord"
            }
          },
          "date_created": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de creación del dominio"
          },
          "date_changed": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de la última actualización del dominio"
          }
        },
        "required": [
          "id",
          "domain",
          "domain_status",
          "verification_status"
        ]
      },
      "DomainDnsRecord": {
        "type": "object",
        "description": "Registro DNS requerido para la verificación del dominio de correo",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "TXT",
              "CNAME",
              "MX"
            ],
            "description": "Tipo de registro DNS"
          },
          "name": {
            "type": "string",
            "description": "Nombre/host del registro DNS (por ejemplo, 'resend._domainkey' o '@')"
          },
          "value": {
            "type": "string",
            "description": "Valor del registro DNS"
          },
          "ttl": {
            "type": "string",
            "description": "Tiempo de vida (por ejemplo, 'Auto' o segundos)"
          },
          "priority": {
            "type": "integer",
            "nullable": true,
            "description": "Prioridad para registros MX"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "verified",
              "failed"
            ],
            "description": "Estado de verificación de este registro específico"
          }
        }
      },
      "EmailTemplate": {
        "type": "object",
        "description": "Plantilla de correo personalizada para las notificaciones de Solicitud de Firma",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identificador único de la plantilla de correo"
          },
          "email_type": {
            "type": "string",
            "enum": [
              "signing_invite",
              "next_signer",
              "signing_expired",
              "signing_cancelled",
              "signing_declined"
            ],
            "description": "Tipo de correo para el que es esta plantilla"
          },
          "subject": {
            "type": "string",
            "description": "Línea de asunto del correo"
          },
          "body": {
            "type": "string",
            "description": "Cuerpo del correo (HTML). Admite placeholders como {{signing_link}}, {{signer_name}}, etc."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de creación de la plantilla"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de la última actualización de la plantilla"
          }
        },
        "required": [
          "email_type",
          "subject",
          "body"
        ]
      },
      "SignerTerms": {
        "type": "object",
        "properties": {
          "language": {
            "type": "string",
            "enum": [
              "en",
              "es",
              "it",
              "pt",
              "fr",
              "de",
              "el",
              "ru",
              "pl"
            ]
          },
          "statement_text": {
            "type": "string",
            "description": "Declaración de consentimiento en HTML depurado"
          },
          "terms_url": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "Enlace externo opcional a los términos"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "language",
          "statement_text"
        ]
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "Mensaje de error legible para humanos"
          },
          "message": {
            "type": "string",
            "description": "Descripción detallada del error"
          },
          "details": {
            "type": "object",
            "description": "Detalles adicionales del error",
            "additionalProperties": true
          }
        },
        "required": [
          "error"
        ]
      },
      "SigningRequestDownloadResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "finished",
              "in_progress",
              "cancelled",
              "declined",
              "expired"
            ],
            "description": "Estado de la Solicitud de Firma. `finished` significa que todos los Firmantes han completado el proceso. `in_progress` significa que la firma sigue en curso y esta es una descarga parcial. `cancelled`, `declined` y `expired` indican estados terminales donde el documento es una instantánea parcial del momento en que terminó la firma."
          },
          "is_partial": {
            "type": "boolean",
            "description": "Si esta URL de descarga apunta a un documento parcialmente firmado (no todos los Firmantes han completado el proceso)."
          },
          "download_url": {
            "type": "string",
            "format": "uri",
            "description": "URL prefirmada para descargar el documento PDF. Expira en el momento indicado por `expires_at`."
          },
          "generated_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Marca de tiempo ISO 8601 de cuándo se generó el documento por última vez. Para descargas parciales, es cuándo se creó el PDF parcial."
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo ISO 8601 de cuándo expira `download_url`. Vuelve a llamar a este endpoint para obtener una URL nueva después de que expire."
          }
        },
        "required": [
          "status",
          "is_partial",
          "download_url",
          "expires_at"
        ]
      },
      "Pagination": {
        "type": "object",
        "properties": {
          "current_page": {
            "type": "integer"
          },
          "page_size": {
            "type": "integer"
          },
          "total_count": {
            "type": "integer"
          },
          "total_pages": {
            "type": "integer"
          }
        },
        "description": "Metadatos de paginación para respuestas de listas",
        "required": [
          "current_page",
          "page_size",
          "total_count",
          "total_pages"
        ]
      },
      "WorkspaceListResponse": {
        "type": "object",
        "description": "Lista paginada de espacios de trabajo",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Workspace"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "results",
          "pagination"
        ]
      },
      "TemplateListResponse": {
        "type": "object",
        "description": "Lista paginada de plantillas",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Template"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "results",
          "pagination"
        ]
      },
      "SigningRequestListResponse": {
        "type": "object",
        "description": "Lista paginada de solicitudes de firma",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SigningRequestListItem"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "results",
          "pagination"
        ]
      },
      "WebhookListResponse": {
        "type": "object",
        "description": "Lista paginada de webhooks",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Webhook"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "results",
          "pagination"
        ]
      },
      "MessageResponse": {
        "type": "object",
        "description": "Respuesta de éxito simple con un mensaje",
        "properties": {
          "message": {
            "type": "string",
            "description": "Mensaje de éxito"
          }
        },
        "required": [
          "message"
        ]
      },
      "TemplateUserListResponse": {
        "type": "object",
        "description": "Lista de usuarios de la plantilla",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TemplateUser"
            }
          }
        },
        "required": [
          "results"
        ]
      },
      "TemplateFieldListResponse": {
        "type": "object",
        "description": "Lista de campos de la plantilla",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TemplateField"
            }
          }
        },
        "required": [
          "results"
        ]
      },
      "SigningRequestUserListResponse": {
        "type": "object",
        "description": "Lista de usuarios de la solicitud de firma",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SigningRequestUser"
            }
          }
        },
        "required": [
          "results"
        ]
      },
      "SigningRequestFieldListResponse": {
        "type": "object",
        "description": "Lista de campos de la solicitud de firma",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SigningRequestField"
            }
          }
        },
        "required": [
          "results"
        ]
      },
      "AuditTrailListResponse": {
        "type": "object",
        "description": "Lista de entradas del registro de auditoría",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "timestamp": {
                  "type": "string",
                  "format": "date-time"
                },
                "source": {
                  "type": "string",
                  "enum": [
                    "admin",
                    "signer"
                  ],
                  "description": "Indica si el evento fue disparado por un admin/API o por un firmante"
                },
                "event": {
                  "type": "string",
                  "description": "Identificador del tipo de evento"
                },
                "description": {
                  "type": "string",
                  "description": "Descripción del evento en formato legible"
                },
                "actor": {
                  "type": "object",
                  "nullable": true,
                  "description": "Quién realizó la acción (nombre/email del firmante o admin/clave API)"
                },
                "ip_address": {
                  "type": "string",
                  "nullable": true,
                  "description": "Dirección IP del firmante (solo eventos de firmante)"
                },
                "details": {
                  "type": "object",
                  "nullable": true,
                  "description": "Metadatos adicionales específicos del evento"
                }
              }
            }
          }
        },
        "required": [
          "results"
        ]
      },
      "CompanyEmailTemplateListResponse": {
        "type": "object",
        "description": "Lista de plantillas de email de la empresa",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EmailTemplate"
            }
          }
        },
        "required": [
          "results"
        ]
      },
      "DomainListResponse": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Domain"
            }
          },
          "workspace_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID del espacio de trabajo para resultados con alcance limitado"
          }
        },
        "description": "Lista de dominios con contexto del espacio de trabajo",
        "required": [
          "results"
        ]
      },
      "DomainCreateResponse": {
        "type": "object",
        "properties": {
          "domain": {
            "$ref": "#/components/schemas/Domain"
          },
          "verification_instructions": {
            "type": "object",
            "properties": {
              "record_type": {
                "type": "string",
                "example": "TXT"
              },
              "record_name": {
                "type": "string",
                "example": "_firma-verification.acme.com"
              },
              "record_value": {
                "type": "string",
                "example": "firma-verify=abc123xyz"
              },
              "next_step": {
                "type": "string",
                "example": "Add this TXT record to your DNS, then call POST /company/domains/{id}/verify-ownership"
              }
            }
          }
        },
        "description": "Dominio creado con instrucciones de verificación",
        "required": [
          "domain",
          "verification_instructions"
        ]
      },
      "DomainDeleteResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "domain_id": {
            "type": "string",
            "format": "uuid"
          }
        },
        "description": "Confirmación de eliminación de dominio",
        "required": [
          "message",
          "domain_id"
        ]
      },
      "DomainVerifyOwnershipResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "domain": {
            "$ref": "#/components/schemas/Domain"
          },
          "next_step": {
            "type": "string"
          }
        },
        "description": "Resultado de la verificación de propiedad del dominio",
        "required": [
          "message",
          "domain",
          "next_step"
        ]
      },
      "DomainFinalizeResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "domain": {
            "$ref": "#/components/schemas/Domain"
          },
          "dns_records": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DomainDnsRecord"
            },
            "description": "Registros DNS a agregar para el envío de emails"
          },
          "next_step": {
            "type": "string"
          }
        },
        "description": "Finalización del dominio con registros DNS",
        "required": [
          "message",
          "domain",
          "dns_records",
          "next_step"
        ]
      },
      "DomainVerifyDnsResponse": {
        "type": "object",
        "properties": {
          "verified": {
            "type": "boolean",
            "description": "Indica si todos los registros DNS están verificados"
          },
          "message": {
            "type": "string"
          },
          "domain": {
            "$ref": "#/components/schemas/Domain"
          },
          "dns_records": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DomainDnsRecord"
            },
            "description": "Estado de cada registro DNS"
          }
        },
        "description": "Resultado de la verificación DNS",
        "required": [
          "verified",
          "message",
          "domain"
        ]
      },
      "DomainSetPrimaryResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "domain": {
            "$ref": "#/components/schemas/Domain"
          }
        },
        "description": "Confirmación de actualización del dominio principal",
        "required": [
          "message",
          "domain"
        ]
      },
      "RotateSecretResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "new_secret": {
            "type": "string",
            "description": "El nuevo secreto de firma del webhook (cadena hexadecimal de 64 caracteres)"
          },
          "grace_period_hours": {
            "type": "integer",
            "description": "Horas durante las cuales el secreto anterior sigue siendo válido junto con el nuevo"
          },
          "warning": {
            "type": "string",
            "description": "Recordatorio para actualizar la verificación de firma del webhook"
          }
        },
        "description": "Resultado de la rotación del secreto con periodo de gracia",
        "required": [
          "message",
          "new_secret",
          "grace_period_hours"
        ]
      },
      "SecretStatusResponse": {
        "type": "object",
        "properties": {
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Cuándo se creó el secreto del webhook",
            "nullable": true
          },
          "last_rotated_at": {
            "type": "string",
            "format": "date-time",
            "description": "Cuándo se rotó por última vez el secreto del webhook",
            "nullable": true
          },
          "grace_period_active": {
            "type": "boolean",
            "description": "Indica si el secreto anterior sigue siendo válido junto con el nuevo"
          },
          "grace_period_ends_at": {
            "type": "string",
            "format": "date-time",
            "description": "Cuándo expira el periodo de gracia del secreto anterior",
            "nullable": true
          }
        },
        "description": "Estado del secreto del webhook e información de rotación",
        "required": [
          "created_at"
        ]
      },
      "EmailTemplateDeleteResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "email_type": {
            "type": "string"
          }
        },
        "description": "Confirmación de eliminación de la plantilla de email",
        "required": [
          "message",
          "email_type"
        ]
      },
      "SignerTermsListResponse": {
        "type": "object",
        "properties": {
          "terms": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SignerTerms"
            }
          }
        },
        "description": "Lista de términos del firmante por idioma",
        "required": [
          "terms"
        ]
      },
      "SignerTermsUpdateResponse": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "storedHtml": {
            "type": "string",
            "description": "El HTML saneado que realmente se almacenó"
          },
          "changed": {
            "type": "boolean",
            "description": "Indica si el saneamiento alteró la declaración enviada"
          }
        },
        "description": "Resultado de la actualización de términos del firmante",
        "required": [
          "ok"
        ]
      },
      "SignerTermsDeleteResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "language": {
            "type": "string"
          }
        },
        "description": "Confirmación de eliminación de términos del firmante",
        "required": [
          "message",
          "language"
        ]
      },
      "CustomFieldListResponse": {
        "type": "object",
        "properties": {
          "custom_fields": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WorkspaceCustomField"
            }
          }
        },
        "description": "Lista de campos personalizados",
        "required": [
          "custom_fields"
        ]
      },
      "LogoUploadResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "icon_url": {
            "type": "string",
            "format": "uri",
            "description": "URL pública del logo subido"
          }
        },
        "description": "Confirmación de subida del logo con URL",
        "required": [
          "success",
          "icon_url"
        ]
      },
      "LogoDeleteResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          }
        },
        "description": "Confirmación de eliminación del logo",
        "required": [
          "success"
        ]
      },
      "ApiKeyRegenerateResponse": {
        "type": "object",
        "properties": {
          "new_key": {
            "type": "object",
            "description": "La clave API recién generada",
            "properties": {
              "api_key": {
                "type": "string",
                "description": "El valor de la nueva clave API"
              },
              "created_at": {
                "type": "string",
                "format": "date-time",
                "description": "Cuándo se creó la clave"
              }
            }
          },
          "key_type": {
            "type": "string",
            "enum": [
              "live",
              "test"
            ],
            "description": "El tipo de clave que fue regenerada"
          },
          "expiring_keys": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "api_key": {
                  "type": "string",
                  "description": "El valor de la clave API por expirar"
                },
                "expires_at": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            },
            "description": "Lista de claves configuradas para expirar en 24 horas"
          },
          "workspace_id": {
            "type": "string",
            "format": "uuid"
          }
        },
        "description": "Resultado de la regeneración de la clave API",
        "required": [
          "new_key",
          "key_type",
          "workspace_id"
        ]
      },
      "ApiKeyExpireResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "description": "Indica si la operación tuvo éxito"
          },
          "expired_keys": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "api_key": {
                  "type": "string",
                  "description": "El valor de la clave API expirada"
                },
                "original_expires_at": {
                  "type": "string",
                  "format": "date-time",
                  "description": "Cuándo estaba originalmente programado que expirara la clave"
                },
                "expired_at": {
                  "type": "string",
                  "format": "date-time",
                  "description": "Cuándo expiró realmente la clave"
                }
              }
            },
            "description": "Lista de claves expiradas con detalles"
          },
          "workspace_id": {
            "type": "string",
            "format": "uuid"
          },
          "message": {
            "type": "string",
            "description": "Mensaje opcional cuando no hay claves pendientes"
          }
        },
        "description": "Resultado de la expiración de la clave API",
        "required": [
          "success",
          "workspace_id"
        ]
      },
      "TemplatePatchResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "updated_fields": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Se devuelve al actualizar propiedades"
          },
          "user": {
            "type": "object",
            "description": "Se devuelve al actualizar/crear un usuario"
          }
        },
        "description": "Resultado de la actualización parcial de la plantilla",
        "required": [
          "message",
          "updated_fields"
        ]
      },
      "TemplateDuplicateResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "ID de la solicitud de firma recién creada"
          },
          "name": {
            "type": "string",
            "description": "Nombre de la nueva solicitud de firma"
          },
          "description": {
            "type": "string",
            "nullable": true,
            "description": "Descripción de la nueva solicitud de firma"
          },
          "status": {
            "type": "string",
            "description": "Estado de la nueva solicitud de firma",
            "example": "draft"
          },
          "workspace_id": {
            "type": "string",
            "format": "uuid",
            "description": "Espacio de trabajo al que pertenece la solicitud de firma"
          },
          "created_date": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de creación"
          }
        },
        "description": "Detalles de la plantilla duplicada",
        "required": [
          "id",
          "name",
          "status",
          "workspace_id"
        ]
      },
      "CreateAndSendResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "ID de la solicitud de firma"
          },
          "name": {
            "type": "string",
            "description": "Nombre de la solicitud de firma"
          },
          "description": {
            "type": "string",
            "nullable": true,
            "description": "Descripción de la solicitud de firma"
          },
          "status": {
            "type": "string",
            "enum": [
              "sent"
            ],
            "description": "Siempre 'sent' para este endpoint"
          },
          "document_url": {
            "type": "string",
            "format": "uri",
            "description": "URL firmada para acceder al documento"
          },
          "page_count": {
            "type": "integer",
            "description": "Número de páginas del documento"
          },
          "expiration_hours": {
            "type": "integer",
            "description": "Horas hasta la expiración"
          },
          "settings": {
            "$ref": "#/components/schemas/SigningRequestSettings"
          },
          "created_date": {
            "type": "string",
            "format": "date-time"
          },
          "sent_date": {
            "type": "string",
            "format": "date-time",
            "description": "Cuándo se envió la solicitud"
          },
          "template_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "first_signer": {
            "type": "object",
            "description": "Detalles del primer firmante que recibió el email",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "name": {
                "type": "string"
              },
              "email": {
                "type": "string",
                "format": "email"
              },
              "signing_link": {
                "type": "string",
                "format": "uri",
                "description": "Enlace directo para que el firmante acceda a la vista de firma"
              }
            }
          },
          "recipients": {
            "type": "array",
            "description": "Todos los destinatarios con UUIDs reales",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "first_name": {
                  "type": "string"
                },
                "last_name": {
                  "type": "string",
                  "nullable": true
                },
                "name": {
                  "type": "string"
                },
                "email": {
                  "type": "string",
                  "format": "email"
                },
                "designation": {
                  "type": "string"
                },
                "order": {
                  "type": "integer"
                }
              }
            }
          },
          "fields": {
            "type": "array",
            "description": "Todos los campos con UUIDs reales de destinatarios",
            "items": {
              "$ref": "#/components/schemas/Field"
            }
          },
          "credits_remaining": {
            "type": "integer",
            "description": "Créditos de la empresa restantes después de la deducción"
          }
        },
        "description": "Solicitud de firma creada y enviada",
        "required": [
          "id",
          "name",
          "status"
        ]
      },
      "CreateAndSendValidationError": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          },
          "code": {
            "type": "string",
            "description": "Código de error legible por máquina",
            "example": "VALIDATION_ERROR"
          },
          "phase": {
            "type": "string",
            "enum": [
              "create_validation",
              "send_validation"
            ],
            "description": "Qué fase de validación falló"
          },
          "validation_errors": {
            "type": "array",
            "description": "Errores de validación detallados de la fase de envío",
            "items": {
              "type": "object",
              "properties": {
                "recipient_index": {
                  "type": "integer",
                  "description": "Índice del destinatario (basado en 1)"
                },
                "recipient_email": {
                  "type": "string"
                },
                "missing_fields": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  },
                  "description": "Lista de campos requeridos faltantes"
                }
              }
            }
          }
        },
        "description": "Error de validación durante create-and-send",
        "required": [
          "error",
          "code"
        ]
      },
      "InsufficientCreditsError": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "example": "Insufficient credits. Please purchase more credits to send signing requests."
          },
          "code": {
            "type": "string",
            "example": "INSUFFICIENT_CREDITS"
          },
          "current_credits": {
            "type": "integer",
            "example": 0
          }
        },
        "description": "Error de créditos insuficientes",
        "required": [
          "error",
          "code",
          "current_credits"
        ]
      },
      "UnprocessableEntityError": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "example": "A recipient's email address cannot receive messages."
          },
          "code": {
            "type": "string",
            "example": "RECIPIENT_EMAIL_SUPPRESSED"
          }
        },
        "description": "Error de entidad no procesable",
        "required": [
          "error",
          "code"
        ]
      },
      "SigningRequestUpdateResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "ID de la solicitud de firma (por compatibilidad con versiones anteriores)"
          },
          "name": {
            "type": "string",
            "description": "Nombre de la solicitud de firma (por compatibilidad con versiones anteriores)"
          },
          "signing_request": {
            "type": "object",
            "description": "Resumen de la solicitud de firma actualizada (subconjunto del esquema completo de SigningRequest)",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid",
                "description": "ID de la solicitud de firma"
              },
              "name": {
                "type": "string",
                "description": "Nombre de la solicitud de firma"
              },
              "description": {
                "type": "string",
                "nullable": true,
                "description": "Descripción de la solicitud de firma (mapeada desde template_description)"
              },
              "document_url": {
                "type": "string",
                "format": "uri",
                "description": "URL prefirmada al documento PDF"
              },
              "document_url_expires_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Cuándo expira la URL del documento"
              },
              "document_page_count": {
                "type": "integer",
                "description": "Número de páginas del documento"
              },
              "status": {
                "type": "string",
                "description": "Estado actual de la solicitud de firma"
              },
              "expiration_hours": {
                "type": "integer",
                "description": "Horas hasta que expira la solicitud de firma"
              },
              "settings": {
                "type": "object",
                "description": "Subconjunto de la configuración de la solicitud de firma devuelto en la respuesta PUT",
                "properties": {
                  "allow_download": {
                    "type": "boolean",
                    "description": "Si los destinatarios pueden descargar el documento"
                  },
                  "attach_pdf_on_finish": {
                    "type": "boolean",
                    "description": "Si se debe adjuntar el PDF al finalizar"
                  },
                  "hand_drawn_only": {
                    "type": "boolean",
                    "description": "Si solo se permiten firmas dibujadas a mano"
                  }
                }
              },
              "template_id": {
                "type": "string",
                "format": "uuid",
                "nullable": true,
                "description": "ID de la plantilla si se creó a partir de una plantilla"
              },
              "expires_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Timestamp ISO 8601 de cuándo expira la solicitud de firma"
              },
              "created_date": {
                "type": "string",
                "format": "date-time",
                "description": "Timestamp de creación"
              },
              "sent_date": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Cuándo se envió la solicitud de firma"
              },
              "finished_date": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Cuándo se completaron todas las firmas"
              },
              "cancelled_date": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Cuándo se canceló la solicitud de firma"
              }
            }
          },
          "recipients": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Recipient"
            },
            "description": "Lista actualizada de destinatarios"
          },
          "reminders": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Reminder"
            },
            "description": "Lista actualizada de recordatorios"
          },
          "summary": {
            "type": "object",
            "description": "Resumen de todos los cambios realizados en esta actualización",
            "properties": {
              "properties_updated": {
                "type": "boolean",
                "description": "Si se actualizó alguna propiedad"
              },
              "recipients_created": {
                "type": "integer",
                "description": "Número de destinatarios nuevos creados"
              },
              "recipients_updated": {
                "type": "integer",
                "description": "Número de destinatarios existentes actualizados"
              },
              "recipients_deleted": {
                "type": "integer",
                "description": "Número de destinatarios eliminados de forma reversible (soft-delete)"
              },
              "fields_created": {
                "type": "integer",
                "description": "Número de campos nuevos creados"
              },
              "fields_updated": {
                "type": "integer",
                "description": "Número de campos existentes actualizados"
              },
              "fields_reassigned": {
                "type": "integer",
                "description": "Número de campos reasignados a otro destinatario"
              },
              "fields_deleted": {
                "type": "integer",
                "description": "Número de campos eliminados de forma reversible (soft-delete)"
              },
              "reminders_created": {
                "type": "integer",
                "description": "Número de recordatorios nuevos creados"
              },
              "reminders_updated": {
                "type": "integer",
                "description": "Número de recordatorios existentes actualizados"
              },
              "warnings": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "Advertencias de formato de email para destinatarios (no bloqueantes)"
              }
            }
          }
        },
        "description": "Resultado de la actualización de la solicitud de firma",
        "required": [
          "id",
          "name"
        ]
      },
      "SigningRequestUpdateError": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "details": {
            "type": "object",
            "properties": {
              "signing_request_properties": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "recipients": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "deleted_recipients": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "fields": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "reminders": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          }
        },
        "description": "Error de validación al actualizar la solicitud de firma",
        "required": [
          "error"
        ]
      },
      "SigningRequestDeleteResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "signing_request_id": {
            "type": "string",
            "format": "uuid"
          },
          "deleted_on": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "Confirmación de eliminación de la solicitud de firma",
        "required": [
          "message",
          "signing_request_id"
        ]
      },
      "CancelSigningRequestResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "signing_request_id": {
            "type": "string",
            "format": "uuid"
          },
          "cancelled_on": {
            "type": "string",
            "format": "date-time"
          },
          "notify_signers": {
            "type": "boolean"
          },
          "emails_sent": {
            "type": "integer",
            "description": "Número de emails de notificación de cancelación enviados a los firmantes"
          }
        },
        "description": "Resultado de la cancelación de la solicitud de firma",
        "required": [
          "message",
          "signing_request_id",
          "cancelled_on"
        ]
      },
      "ResendSigningRequestResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "signing_request_id": {
            "type": "string",
            "format": "uuid"
          },
          "recipients_notified": {
            "type": "integer"
          },
          "recipients_failed": {
            "type": "integer",
            "description": "Número de destinatarios cuya notificación de reenvío no pudo enviarse"
          },
          "recipients": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "email": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                }
              }
            }
          }
        },
        "description": "Resultado del reenvío de la solicitud de firma",
        "required": [
          "message",
          "signing_request_id"
        ]
      },
      "ResendConflictError": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "details": {
            "type": "object",
            "properties": {
              "current_order": {
                "type": "integer"
              },
              "invalid_recipients": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "email": {
                      "type": "string"
                    },
                    "order": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          }
        },
        "description": "Error de conflicto de reenvío",
        "required": [
          "error",
          "code"
        ]
      },
      "TestWebhookResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "description": "Si el webhook de prueba se entregó correctamente"
          },
          "status_code": {
            "type": "integer",
            "description": "Código de estado HTTP devuelto por el endpoint del webhook"
          },
          "webhook_event_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID del registro del evento de webhook"
          },
          "message": {
            "type": "string"
          },
          "headers_sent": {
            "type": "object",
            "description": "Headers enviados con la solicitud de webhook de prueba",
            "properties": {
              "X-Firma-Event": {
                "type": "string"
              },
              "X-Firma-Signature": {
                "type": "string"
              },
              "X-Firma-Delivery": {
                "type": "string"
              },
              "X-Firma-Signature-Old": {
                "type": "string",
                "description": "Solo presente durante el período de gracia tras la rotación del secreto"
              }
            }
          }
        },
        "description": "Resultado de la ejecución de la prueba de webhook",
        "required": [
          "success",
          "status_code"
        ]
      },
      "GenerateTemplateTokenResponse": {
        "type": "object",
        "properties": {
          "token": {
            "type": "string",
            "description": "El token JWT"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp de expiración del token"
          },
          "jwt_record_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID del registro en la base de datos para el JWT"
          }
        },
        "description": "Token JWT generado para la plantilla",
        "required": [
          "token",
          "expires_at"
        ]
      },
      "EmailTemplateDefaultsResponse": {
        "type": "object",
        "properties": {
          "language": {
            "type": "string"
          },
          "templates": {
            "type": "object",
            "description": "Mapa de email_type a la plantilla predeterminada {subject, body}",
            "additionalProperties": {
              "type": "object",
              "properties": {
                "subject": {
                  "type": "string"
                },
                "body": {
                  "type": "string"
                }
              }
            }
          }
        },
        "description": "Plantillas de email predeterminadas para un idioma",
        "required": [
          "language",
          "templates"
        ]
      },
      "EmailTemplatePlaceholdersResponse": {
        "type": "object",
        "properties": {
          "placeholders": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "key": {
                  "type": "string",
                  "description": "Clave del placeholder (por ejemplo, 'signing_link')"
                },
                "description": {
                  "type": "string",
                  "description": "A qué se resuelve este placeholder"
                }
              }
            }
          }
        },
        "description": "Placeholders disponibles para plantillas de email",
        "required": [
          "placeholders"
        ]
      },
      "WorkspaceEmailTemplateListResponse": {
        "type": "object",
        "description": "Lista de plantillas de email del espacio de trabajo",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EmailTemplate"
            }
          },
          "workspace_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID del espacio de trabajo"
          }
        },
        "required": [
          "results",
          "workspace_id"
        ]
      }
    }
  },
  "paths": {
    "/company": {
      "get": {
        "summary": "Obtener información de la empresa",
        "description": "Recuperar información sobre la empresa autenticada",
        "tags": [
          "Company"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Información de la empresa recuperada correctamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 200 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solicitudes restantes en la ventana actual"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Timestamp Unix de cuándo se restablece el límite de tasa"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Company"
                },
                "example": {
                  "id": "123e4567-e89b-12d3-a456-426614174000",
                  "name": "Acme Corporation",
                  "language": "en",
                  "account_owner": "John Doe",
                  "account_owner_email": "john@acme.com",
                  "website": "https://acme.com",
                  "icon_url": "https://acme.com/logo.png",
                  "credits": 1000,
                  "created_date": "2024-01-15T10:30:00Z",
                  "updated_date": "2024-03-20T14:25:00Z"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "getCompany",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.company.getCompany();\nconsole.log(response);"
          }
        ]
      },
      "put": {
        "summary": "Actualizar información de la empresa",
        "description": "Actualizar todos los detalles de la empresa. Esta es una operación de reemplazo completo que requiere todos los campos excepto icon_url.",
        "tags": [
          "Company"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "account_owner",
                  "account_owner_email",
                  "website"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Nombre de la empresa"
                  },
                  "language": {
                    "type": "string",
                    "enum": [
                      "en",
                      "es",
                      "it",
                      "pt",
                      "fr",
                      "de",
                      "el",
                      "ru",
                      "pl"
                    ],
                    "description": "Idioma predeterminado de la empresa"
                  },
                  "account_owner": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Nombre del propietario de la cuenta"
                  },
                  "account_owner_email": {
                    "type": "string",
                    "format": "email",
                    "description": "Dirección de email del propietario de la cuenta"
                  },
                  "website": {
                    "type": "string",
                    "format": "uri",
                    "description": "URL del sitio web de la empresa"
                  }
                },
                "additionalProperties": false
              },
              "example": {
                "name": "Acme Corporation Ltd",
                "account_owner": "Jane Smith",
                "account_owner_email": "jane@acme.com",
                "website": "https://www.acme.com"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Empresa actualizada correctamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 120 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solicitudes restantes en la ventana actual"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Timestamp Unix de cuándo se restablece el límite de tasa"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Company"
                }
              }
            }
          },
          "400": {
            "description": "Error de validación",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "protectedFields": {
                    "summary": "Se intentó modificar campos protegidos",
                    "value": {
                      "error": "The following fields cannot be modified: credits",
                      "code": "VALIDATION_ERROR"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "updateCompany",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.company.updateCompany({\n    name: \"Acme Corporation Ltd\",\n    account_owner: \"Jane Smith\",\n    account_owner_email: \"jane@acme.com\",\n    website: \"https://www.acme.com\"\n});\nconsole.log(response);"
          }
        ]
      },
      "patch": {
        "summary": "Actualizar parcialmente la información de la empresa",
        "description": "Actualizar campos específicos de la empresa. Solo se actualizarán los campos proporcionados. Se debe proporcionar al menos un campo.",
        "tags": [
          "Company"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Nombre de la empresa"
                  },
                  "language": {
                    "type": "string",
                    "enum": [
                      "en",
                      "es",
                      "it",
                      "pt",
                      "fr",
                      "de",
                      "el",
                      "ru",
                      "pl"
                    ],
                    "description": "Idioma predeterminado de la empresa"
                  },
                  "account_owner": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Nombre del propietario de la cuenta"
                  },
                  "account_owner_email": {
                    "type": "string",
                    "format": "email",
                    "description": "Dirección de email del propietario de la cuenta"
                  },
                  "website": {
                    "type": "string",
                    "format": "uri",
                    "description": "URL del sitio web de la empresa"
                  }
                },
                "additionalProperties": false
              },
              "example": {
                "name": "Acme Corporation Ltd",
                "website": "https://www.acme.com"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Empresa actualizada correctamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 120 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solicitudes restantes en la ventana actual"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Timestamp Unix de cuándo se restablece el límite de tasa"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Company"
                }
              }
            }
          },
          "400": {
            "description": "Error de validación",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "protectedFields": {
                    "summary": "Se intentó modificar campos protegidos",
                    "value": {
                      "error": "The following fields cannot be modified: credits",
                      "code": "VALIDATION_ERROR"
                    }
                  },
                  "noFields": {
                    "summary": "No se proporcionaron campos",
                    "value": {
                      "error": "Validation failed",
                      "details": [
                        {
                          "path": [
                            "body"
                          ],
                          "message": "No fields provided to update"
                        }
                      ]
                    }
                  },
                  "invalidEmail": {
                    "summary": "Email inválido",
                    "value": {
                      "error": "Validation failed",
                      "details": [
                        {
                          "path": [
                            "account_owner_email"
                          ],
                          "message": "Invalid email address"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "patchCompany",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.company.patchCompany({\n    name: \"Acme Corporation Ltd\",\n    website: \"https://www.acme.com\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/company/settings": {
      "get": {
        "summary": "Obtener configuración de la empresa",
        "description": "Recuperar la configuración de la empresa autenticada",
        "tags": [
          "Company"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Configuración de la empresa recuperada correctamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompanySettings"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "getCompanySettings",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.company.getCompanySettings();\nconsole.log(response);"
          }
        ]
      },
      "put": {
        "summary": "Actualizar configuración de la empresa",
        "description": "Actualizar la configuración de la empresa. Solo se actualizarán los campos proporcionados.",
        "tags": [
          "Company"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "default_expiration_hours": {
                    "type": "integer",
                    "minimum": 1,
                    "description": "Expiración predeterminada de la solicitud de firma en horas"
                  },
                  "require_terms_acceptance": {
                    "type": "boolean",
                    "description": "Si los firmantes deben aceptar los términos antes de firmar"
                  },
                  "show_custom_branding_only": {
                    "type": "boolean"
                  },
                  "require_otp_verification": {
                    "type": "boolean"
                  },
                  "allow_presigning_download": {
                    "type": "boolean"
                  },
                  "disable_guided_navigation": {
                    "type": "boolean"
                  },
                  "show_signature_frame": {
                    "type": "boolean"
                  },
                  "show_partial_watermark": {
                    "type": "boolean"
                  },
                  "email_local_part": {
                    "type": "string"
                  },
                  "color_primary": {
                    "type": "string",
                    "nullable": true,
                    "pattern": "^#[0-9A-Fa-f]{6}$"
                  },
                  "color_primary_fg": {
                    "type": "string",
                    "nullable": true,
                    "pattern": "^#[0-9A-Fa-f]{6}$"
                  },
                  "color_background": {
                    "type": "string",
                    "nullable": true,
                    "pattern": "^#[0-9A-Fa-f]{6}$"
                  },
                  "color_foreground": {
                    "type": "string",
                    "nullable": true,
                    "pattern": "^#[0-9A-Fa-f]{6}$"
                  },
                  "color_card": {
                    "type": "string",
                    "nullable": true,
                    "pattern": "^#[0-9A-Fa-f]{6}$"
                  },
                  "color_border": {
                    "type": "string",
                    "nullable": true,
                    "pattern": "^#[0-9A-Fa-f]{6}$"
                  },
                  "color_accent": {
                    "type": "string",
                    "nullable": true,
                    "pattern": "^#[0-9A-Fa-f]{6}$"
                  },
                  "color_accent_fg": {
                    "type": "string",
                    "nullable": true,
                    "pattern": "^#[0-9A-Fa-f]{6}$"
                  },
                  "color_canvas": {
                    "type": "string",
                    "nullable": true,
                    "pattern": "^#[0-9A-Fa-f]{6}$"
                  },
                  "color_muted": {
                    "type": "string",
                    "nullable": true,
                    "pattern": "^#[0-9A-Fa-f]{6}$"
                  },
                  "color_muted_fg": {
                    "type": "string",
                    "nullable": true,
                    "pattern": "^#[0-9A-Fa-f]{6}$"
                  },
                  "show_qr_code": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "Muestra un código QR en la página de firma que permite a los firmantes continuar en su teléfono. Este es el valor predeterminado a nivel de empresa; los espacios de trabajo, plantillas y solicitudes de firma pueden anularlo."
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Configuración de la empresa actualizada correctamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompanySettings"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "updateCompanySettings",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.company.updateCompanySettings();\nconsole.log(response);"
          }
        ]
      }
    },
    "/company/domains": {
      "get": {
        "summary": "Listar dominios de la empresa",
        "description": "Lista todos los dominios de correo electrónico configurados para la empresa (dominios en el espacio de trabajo protegido/predeterminado). Estos dominios se usan como dominio de envío predeterminado para todos los espacios de trabajo.",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Dominios de la empresa obtenidos correctamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 200 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DomainListResponse"
                },
                "example": {
                  "results": [
                    {
                      "id": "123e4567-e89b-12d3-a456-426614174000",
                      "domain": "acme.com",
                      "verification_status": 2,
                      "domain_status": 1,
                      "is_primary": true,
                      "date_created": "2024-01-15T10:30:00Z",
                      "date_changed": "2024-01-16T14:00:00Z"
                    }
                  ],
                  "workspace_id": "456e4567-e89b-12d3-a456-426614174000"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "listCompanyDomains",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailDomains.listCompanyDomains();\nconsole.log(response);"
          }
        ]
      },
      "post": {
        "summary": "Agregar dominio de empresa",
        "description": "Agrega un nuevo dominio de correo electrónico para la empresa. Esto inicia el proceso de verificación del dominio. Después de la creación, debes:\n1. Agregar un registro TXT a tu DNS con el token de verificación\n2. Llamar a POST /company/domains/{id}/verify-ownership para verificar la propiedad del dominio\n3. Llamar a POST /company/domains/{id}/finalize para registrarlo con el proveedor de correo electrónico\n4. Agregar los registros DNS devueltos (SPF, DKIM, etc.)\n5. Llamar a POST /company/domains/{id}/verify-dns para completar la verificación",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "domain"
                ],
                "properties": {
                  "domain": {
                    "type": "string",
                    "description": "Nombre de dominio a agregar (por ejemplo, 'example.com'). Debe tener un formato de dominio válido.",
                    "example": "acme.com"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Dominio creado correctamente. Agrega el registro TXT de verificación a tu DNS.",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 120 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DomainCreateResponse"
                },
                "example": {
                  "domain": {
                    "id": "123e4567-e89b-12d3-a456-426614174000",
                    "domain": "acme.com",
                    "verification_status": 0,
                    "domain_status": 0,
                    "is_primary": false,
                    "verification_token": "firma-verify=abc123xyz",
                    "date_created": "2024-01-15T10:30:00Z",
                    "date_changed": "2024-01-15T10:30:00Z"
                  },
                  "verification_instructions": {
                    "record_type": "TXT",
                    "record_name": "_firma-verification.acme.com",
                    "record_value": "firma-verify=abc123xyz",
                    "next_step": "Add this TXT record to your DNS, then call POST /company/domains/{id}/verify-ownership"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Formato de dominio inválido o el dominio ya existe",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "invalidDomain": {
                    "value": {
                      "error": "Invalid domain format",
                      "message": "Please provide a valid domain name (e.g., example.com)"
                    }
                  },
                  "domainExists": {
                    "value": {
                      "error": "Domain already exists",
                      "message": "This domain is already configured for your company"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "createCompanyDomain",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailDomains.createCompanyDomain({\n    domain: \"acme.com\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/company/domains/{id}": {
      "get": {
        "summary": "Obtener dominio de empresa",
        "description": "Recupera los detalles de un dominio de empresa específico, incluyendo el estado de verificación y los registros DNS",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID del dominio"
          }
        ],
        "responses": {
          "200": {
            "description": "Dominio obtenido correctamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Domain"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "getCompanyDomain",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailDomains.getCompanyDomain({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      },
      "delete": {
        "summary": "Eliminar dominio de empresa",
        "description": "Elimina un dominio de la empresa. Si el dominio es el principal o el único dominio, el envío vuelve a la empresa o al remitente predeterminado.",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID del dominio"
          }
        ],
        "responses": {
          "200": {
            "description": "Dominio eliminado correctamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DomainDeleteResponse"
                },
                "example": {
                  "message": "Domain deleted successfully",
                  "domain_id": "123e4567-e89b-12d3-a456-426614174000"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "deleteCompanyDomain",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailDomains.deleteCompanyDomain({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/company/domains/{id}/verify-ownership": {
      "post": {
        "summary": "Verificar propiedad del dominio",
        "description": "Verifica la propiedad del dominio comprobando el registro TXT. Llama a esto después de agregar el registro TXT de verificación a tu DNS. La propagación de DNS puede tardar hasta 48 horas, pero normalmente se completa en minutos.",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID del dominio"
          }
        ],
        "responses": {
          "200": {
            "description": "Propiedad del dominio verificada correctamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DomainVerifyOwnershipResponse"
                },
                "example": {
                  "message": "Domain ownership verified",
                  "domain": {
                    "id": "123e4567-e89b-12d3-a456-426614174000",
                    "domain": "acme.com",
                    "verification_status": 1,
                    "domain_status": 0
                  },
                  "next_step": "Call POST /company/domains/{id}/finalize to complete domain setup and receive DNS records for email sending"
                }
              }
            }
          },
          "400": {
            "description": "La verificación falló",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "recordNotFound": {
                    "value": {
                      "error": "Verification failed",
                      "message": "TXT record not found. Please ensure the record is added correctly and DNS has propagated.",
                      "details": {
                        "expected_record": "_firma-verification.acme.com",
                        "expected_value": "firma-verify=abc123xyz"
                      }
                    }
                  },
                  "alreadyVerified": {
                    "value": {
                      "error": "Already verified",
                      "message": "Domain ownership has already been verified"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "verifyCompanyDomainOwnership",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailDomains.verifyCompanyDomainOwnership({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/company/domains/{id}/finalize": {
      "post": {
        "summary": "Finalizar configuración del dominio",
        "description": "Finaliza la configuración del dominio registrándolo con el proveedor de correo electrónico. Esto devuelve los registros DNS (SPF, DKIM, DMARC) que deben agregarse para habilitar el envío de correo. Solo se puede llamar después de verificar la propiedad del dominio.",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID del dominio"
          }
        ],
        "responses": {
          "200": {
            "description": "Dominio finalizado correctamente. Agrega los registros DNS devueltos.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DomainFinalizeResponse"
                },
                "example": {
                  "message": "Domain finalized. Add the following DNS records to enable email sending.",
                  "domain": {
                    "id": "123e4567-e89b-12d3-a456-426614174000",
                    "domain": "acme.com",
                    "verification_status": 2,
                    "domain_status": 0
                  },
                  "dns_records": [
                    {
                      "type": "TXT",
                      "name": "@",
                      "value": "v=spf1 include:amazonses.com ~all",
                      "ttl": "Auto",
                      "status": "pending"
                    },
                    {
                      "type": "CNAME",
                      "name": "resend._domainkey",
                      "value": "resend._domainkey.amazonses.com",
                      "ttl": "Auto",
                      "status": "pending"
                    },
                    {
                      "type": "TXT",
                      "name": "_dmarc",
                      "value": "v=DMARC1; p=none;",
                      "ttl": "Auto",
                      "status": "pending"
                    }
                  ],
                  "next_step": "Add these DNS records, then call POST /company/domains/{id}/verify-dns to complete verification"
                }
              }
            }
          },
          "400": {
            "description": "No se puede finalizar",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "notVerified": {
                    "value": {
                      "error": "Ownership not verified",
                      "message": "Please verify domain ownership first by calling POST /company/domains/{id}/verify-ownership"
                    }
                  },
                  "alreadyFinalized": {
                    "value": {
                      "error": "Already finalized",
                      "message": "Domain has already been finalized"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "finalizeCompanyDomain",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailDomains.finalizeCompanyDomain({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/company/domains/{id}/verify-dns": {
      "post": {
        "summary": "Verificar registros DNS",
        "description": "Verifica que todos los registros DNS requeridos (SPF, DKIM, DMARC) estén configurados correctamente. Llama a esto después de agregar todos los registros DNS del paso de finalización. Una vez verificado, el dominio está listo para enviar correos electrónicos.",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID del dominio"
          }
        ],
        "responses": {
          "200": {
            "description": "Resultado de la verificación de DNS",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DomainVerifyDnsResponse"
                },
                "examples": {
                  "verified": {
                    "summary": "Todos los registros verificados",
                    "value": {
                      "verified": true,
                      "message": "Domain is fully verified and ready to send emails",
                      "domain": {
                        "id": "123e4567-e89b-12d3-a456-426614174000",
                        "domain": "acme.com",
                        "verification_status": 2,
                        "domain_status": 1,
                        "is_primary": true
                      },
                      "dns_records": [
                        {
                          "type": "TXT",
                          "name": "@",
                          "value": "v=spf1 include:amazonses.com ~all",
                          "status": "verified"
                        },
                        {
                          "type": "CNAME",
                          "name": "resend._domainkey",
                          "value": "resend._domainkey.amazonses.com",
                          "status": "verified"
                        },
                        {
                          "type": "TXT",
                          "name": "_dmarc",
                          "value": "v=DMARC1; p=none;",
                          "status": "verified"
                        }
                      ]
                    }
                  },
                  "pending": {
                    "summary": "Algunos registros pendientes",
                    "value": {
                      "verified": false,
                      "message": "Some DNS records are not yet verified. Please check your DNS configuration.",
                      "domain": {
                        "id": "123e4567-e89b-12d3-a456-426614174000",
                        "domain": "acme.com",
                        "verification_status": 2,
                        "domain_status": 0
                      },
                      "dns_records": [
                        {
                          "type": "TXT",
                          "name": "@",
                          "value": "v=spf1 include:amazonses.com ~all",
                          "status": "verified"
                        },
                        {
                          "type": "CNAME",
                          "name": "resend._domainkey",
                          "value": "resend._domainkey.amazonses.com",
                          "status": "pending"
                        },
                        {
                          "type": "TXT",
                          "name": "_dmarc",
                          "value": "v=DMARC1; p=none;",
                          "status": "pending"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Dominio no finalizado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "Domain not finalized",
                  "message": "Please finalize domain setup first by calling POST /company/domains/{id}/finalize"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "verifyCompanyDomainDns",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailDomains.verifyCompanyDomainDns({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/company/domains/{id}/set-primary": {
      "post": {
        "summary": "Establecer dominio principal",
        "description": "Establece un dominio como el dominio de envío principal de la empresa. Solo los dominios completamente verificados (domain_status=1) pueden establecerse como principales.",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID del dominio"
          }
        ],
        "responses": {
          "200": {
            "description": "Dominio principal actualizado correctamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DomainSetPrimaryResponse"
                },
                "example": {
                  "message": "Primary domain updated",
                  "domain": {
                    "id": "123e4567-e89b-12d3-a456-426614174000",
                    "domain": "acme.com",
                    "verification_status": 2,
                    "domain_status": 1,
                    "is_primary": true
                  }
                }
              }
            }
          },
          "400": {
            "description": "Dominio no verificado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "Domain not verified",
                  "message": "Only fully verified domains can be set as primary"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "setCompanyPrimaryDomain",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailDomains.setCompanyPrimaryDomain({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/workspaces": {
      "get": {
        "summary": "Listar espacios de trabajo",
        "description": "Recupera una lista paginada de espacios de trabajo para la empresa autenticada",
        "tags": [
          "Workspaces"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Número de página para la paginación",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "page_size",
            "in": "query",
            "description": "Cantidad de elementos por página",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "name",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filtrar por nombre de espacio de trabajo (coincidencia parcial, sin distinción entre mayúsculas y minúsculas)"
          },
          {
            "name": "protected",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "0",
                "1",
                "true",
                "false"
              ]
            },
            "description": "Filtrar por estado de protección"
          },
          {
            "name": "created_after",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Filtrar espacios de trabajo creados después de esta fecha (formato ISO 8601)"
          },
          {
            "name": "created_before",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Filtrar espacios de trabajo creados antes de esta fecha (formato ISO 8601)"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "name",
                "protected",
                "created_on"
              ],
              "default": "created_on"
            },
            "description": "Campo por el cual ordenar"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Orden de clasificación"
          }
        ],
        "responses": {
          "200": {
            "description": "Espacios de trabajo obtenidos correctamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 200 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solicitudes restantes en la ventana actual"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Marca de tiempo Unix en la que se restablece el límite de tasa"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkspaceListResponse"
                },
                "example": {
                  "results": [
                    {
                      "id": "789e4567-e89b-12d3-a456-426614174000",
                      "name": "Sales Workspace",
                      "protected": false,
                      "api_key": "fk_a1b2c3d4e5f6g7h8i9j0",
                      "created_date": "2024-01-20T09:00:00Z",
                      "updated_date": "2024-01-20T09:00:00Z"
                    },
                    {
                      "id": "456e4567-e89b-12d3-a456-426614174000",
                      "name": "Default Workspace",
                      "protected": true,
                      "api_key": "fk_z9y8x7w6v5u4t3s2r1q0",
                      "created_date": "2024-01-15T10:30:00Z",
                      "updated_date": "2024-01-15T10:30:00Z"
                    }
                  ],
                  "pagination": {
                    "current_page": 1,
                    "page_size": 20,
                    "total_count": 2,
                    "total_pages": 1
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error de validación: formato de fecha o parámetros de ordenación inválidos",
            "content": {
              "application/json": {
                "examples": {
                  "invalidDate": {
                    "summary": "Formato de fecha inválido",
                    "value": {
                      "error": "Validation failed",
                      "code": "VALIDATION_ERROR",
                      "details": [
                        {
                          "path": [
                            "created_after"
                          ],
                          "message": "created_after must be a valid ISO 8601 date"
                        }
                      ]
                    }
                  },
                  "invalidSort": {
                    "summary": "Parámetro de ordenación inválido",
                    "value": {
                      "error": "Validation failed",
                      "code": "VALIDATION_ERROR",
                      "details": [
                        {
                          "path": [
                            "sort_order"
                          ],
                          "message": "sort_order must be either 'asc' or 'desc'"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "listWorkspaces",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.workspaces.listWorkspaces();\nconsole.log(response);"
          }
        ]
      },
      "post": {
        "summary": "Crear un nuevo espacio de trabajo",
        "description": "Crea un nuevo espacio de trabajo para la empresa autenticada. Todos los espacios de trabajo se crean como no protegidos de forma predeterminada. El estado de protección solo se puede establecer durante la creación de la cuenta de la empresa.",
        "tags": [
          "Workspaces"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Nombre del espacio de trabajo"
                  }
                }
              },
              "example": {
                "name": "Marketing Workspace"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Espacio de trabajo creado correctamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 120 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solicitudes restantes en la ventana actual"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Marca de tiempo Unix en la que se restablece el límite de tasa"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Workspace"
                },
                "example": {
                  "id": "abc12345-e89b-12d3-a456-426614174000",
                  "name": "Marketing Workspace",
                  "protected": false,
                  "api_key": "fk_m1n2o3p4q5r6s7t8u9v0",
                  "created_date": "2024-01-25T14:00:00Z",
                  "updated_date": "2024-01-25T14:00:00Z"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "createWorkspace",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.workspaces.createWorkspace({\n    name: \"Marketing Workspace\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/workspaces/{id}": {
      "get": {
        "summary": "Obtener un espacio de trabajo",
        "description": "Recupera un espacio de trabajo específico por ID, incluyendo su clave API",
        "tags": [
          "Workspaces"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID del espacio de trabajo",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Espacio de trabajo recuperado exitosamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 200 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solicitudes restantes en la ventana actual"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Marca de tiempo Unix en la que se restablece el límite de tasa"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Workspace"
                },
                "example": {
                  "id": "789e4567-e89b-12d3-a456-426614174000",
                  "name": "Sales Workspace",
                  "protected": false,
                  "api_key": "fk_a1b2c3d4e5f6g7h8i9j0",
                  "created_date": "2024-01-20T09:00:00Z",
                  "updated_date": "2024-01-20T09:00:00Z",
                  "webhook_enabled": false,
                  "webhook_secret": null,
                  "webhook_secret_rotated_at": null,
                  "webhook_secret_created_at": null,
                  "ignore_company_webhooks": false
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "getWorkspace",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.workspaces.getWorkspace({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      },
      "put": {
        "summary": "Actualizar un espacio de trabajo",
        "description": "Actualiza la información de un espacio de trabajo existente. Esta es una operación de reemplazo completo que requiere el campo name.",
        "tags": [
          "Workspaces"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID del espacio de trabajo",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Nombre del espacio de trabajo"
                  }
                }
              },
              "example": {
                "name": "Enterprise Sales Workspace"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Espacio de trabajo actualizado exitosamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 120 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solicitudes restantes en la ventana actual"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Marca de tiempo Unix en la que se restablece el límite de tasa"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Workspace"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "updateWorkspace",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.workspaces.updateWorkspace({\n    id: \"id\",\n    name: \"Enterprise Sales Workspace\"\n});\nconsole.log(response);"
          }
        ]
      },
      "patch": {
        "summary": "Actualizar parcialmente un espacio de trabajo",
        "description": "Actualiza campos específicos del espacio de trabajo. Solo se puede actualizar el name a través de la API. El campo protected es de solo lectura y solo puede establecerse durante la creación de la cuenta de empresa.",
        "tags": [
          "Workspaces"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID del espacio de trabajo",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Nombre del espacio de trabajo"
                  }
                }
              },
              "example": {
                "name": "Updated Workspace Name"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Espacio de trabajo actualizado exitosamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 120 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solicitudes restantes en la ventana actual"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Marca de tiempo Unix en la que se restablece el límite de tasa"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Workspace"
                }
              }
            }
          },
          "400": {
            "description": "Error de validación",
            "content": {
              "application/json": {
                "examples": {
                  "protectedField": {
                    "summary": "Se intentó actualizar un campo protegido",
                    "value": {
                      "error": "Validation failed",
                      "details": [
                        {
                          "path": [
                            "protected"
                          ],
                          "message": "The 'protected' field cannot be updated via API"
                        }
                      ]
                    }
                  },
                  "noFields": {
                    "summary": "No se proporcionaron campos",
                    "value": {
                      "error": "Validation failed",
                      "details": [
                        {
                          "path": [
                            "body"
                          ],
                          "message": "No fields provided to update"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "patchWorkspace",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.workspaces.patchWorkspace({\n    id: \"id\",\n    name: \"Updated Workspace Name\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/workspaces/{id}/api-key/regenerate": {
      "post": {
        "summary": "Regenerar la clave API del espacio de trabajo",
        "description": "Regenera la clave API de un espacio de trabajo. Establece una expiración de 24 horas en las claves activas existentes y crea una nueva clave. No se puede usar en espacios de trabajo protegidos. Limitado a 1 solicitud por minuto.",
        "tags": [
          "Workspaces"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID del espacio de trabajo",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "key_type": {
                    "type": "string",
                    "enum": [
                      "live",
                      "test"
                    ],
                    "default": "live",
                    "description": "Qué tipo de clave regenerar ('live' o 'test'). Por defecto es 'live'. Regenerar un tipo no expira ni afecta al otro."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Clave API regenerada exitosamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 1 solicitud por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solicitudes restantes en la ventana actual"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Marca de tiempo Unix en la que se restablece el límite de tasa"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiKeyRegenerateResponse"
                },
                "example": {
                  "new_key": {
                    "api_key": "firma_live_abc123xyz...",
                    "created_at": "2024-12-17T10:30:00Z"
                  },
                  "key_type": "live",
                  "expiring_keys": [
                    {
                      "id": "old-key-uuid",
                      "api_key": "firma_old456...",
                      "expires_at": "2024-12-18T10:30:00Z"
                    }
                  ],
                  "workspace_id": "123e4567-e89b-12d3-a456-426614174000"
                }
              }
            }
          },
          "400": {
            "description": "No se puede regenerar la clave para un espacio de trabajo protegido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "Cannot regenerate API key for protected workspace"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "regenerateWorkspaceApiKey",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.workspaces.regenerateWorkspaceApiKey({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/workspaces/{id}/api-key/expire": {
      "post": {
        "summary": "Expirar claves API pendientes",
        "description": "Expira inmediatamente todas las claves API pendientes (aquellas con expires_at establecido) de un espacio de trabajo. Útil después de verificar que la nueva clave funciona correctamente. No se puede usar en espacios de trabajo protegidos. Limitado a 1 solicitud por minuto.",
        "tags": [
          "Workspaces"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID del espacio de trabajo",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "key_type": {
                    "type": "string",
                    "enum": [
                      "live",
                      "test"
                    ],
                    "description": "Opcionalmente, restringe la expiración a un solo tipo de clave ('live' o 'test'). Si se omite, se expiran todas las claves pendientes (comportamiento actual)."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Claves pendientes expiradas exitosamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 1 solicitud por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solicitudes restantes en la ventana actual"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Marca de tiempo Unix en la que se restablece el límite de tasa"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiKeyExpireResponse"
                },
                "example": {
                  "success": true,
                  "expired_keys": [
                    {
                      "id": "old-key-uuid",
                      "api_key": "firma_old456...",
                      "original_expires_at": "2024-12-18T10:30:00Z",
                      "expired_at": "2024-12-17T10:30:00Z"
                    }
                  ],
                  "workspace_id": "123e4567-e89b-12d3-a456-426614174000"
                }
              }
            }
          },
          "400": {
            "description": "No se pueden expirar las claves de un espacio de trabajo protegido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "Cannot expire API keys for protected workspace"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "expireWorkspaceApiKey",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.workspaces.expireWorkspaceApiKey({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/templates": {
      "get": {
        "summary": "Listar Plantillas",
        "description": "Recupera una lista paginada de plantillas",
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            },
            "description": "Número de página"
          },
          {
            "name": "page_size",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "description": "Elementos por página"
          },
          {
            "name": "name",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filtrar por nombre de plantilla (coincidencia parcial, sin distinción entre mayúsculas y minúsculas)"
          },
          {
            "name": "created_after",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Filtrar plantillas creadas después de esta fecha (formato ISO 8601)"
          },
          {
            "name": "created_before",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Filtrar plantillas creadas antes de esta fecha (formato ISO 8601)"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "name",
                "created_on",
                "last_changed_on"
              ],
              "default": "created_on"
            },
            "description": "Campo por el cual ordenar"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Orden de clasificación"
          }
        ],
        "responses": {
          "200": {
            "description": "Plantillas recuperadas exitosamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 200 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "listTemplates",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.templates.listTemplates();\nconsole.log(response);"
          }
        ]
      },
      "post": {
        "summary": "Crear Plantilla",
        "description": "Crea una nueva plantilla con un documento PDF codificado en base64. La API extrae automáticamente el número de páginas del documento.",
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "document"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Nombre de la plantilla",
                    "example": "Employment Contract Template"
                  },
                  "description": {
                    "type": "string",
                    "description": "Descripción de la plantilla",
                    "example": "Standard employment contract for new hires"
                  },
                  "document": {
                    "type": "string",
                    "format": "byte",
                    "description": "Documento PDF o DOCX codificado en base64. Los archivos DOCX se convierten automáticamente a PDF. Tamaño máximo: 20MB. La API extraerá automáticamente el número de páginas del documento. (mutuamente excluyente con document_id)",
                    "example": "JVBERi0xLjQKJeLjz9MKMyAwIG9iago8PC9UeXBlIC9QYWdlCi9QYXJlbnQgMSAwIFIKL1Jlc291c..."
                  },
                  "expiration_hours": {
                    "type": "integer",
                    "description": "Horas hasta que expire la solicitud de firma",
                    "default": 168,
                    "example": 168
                  },
                  "settings": {
                    "type": "object",
                    "properties": {
                      "allow_editing_before_sending": {
                        "type": "boolean",
                        "default": false,
                        "description": "Permitir editar campos antes de enviar"
                      },
                      "attach_pdf_on_finish": {
                        "type": "boolean",
                        "default": true,
                        "description": "Adjuntar el PDF completado al correo de finalización"
                      },
                      "allow_download": {
                        "type": "boolean",
                        "default": true,
                        "description": "Permitir a los destinatarios descargar el documento"
                      },
                      "hand_drawn_only": {
                        "type": "boolean",
                        "default": false,
                        "description": "Requerir que los firmantes dibujen su firma a mano en lugar de usar firmas escritas"
                      },
                      "require_otp_verification": {
                        "type": "boolean",
                        "nullable": true,
                        "default": null,
                        "description": "Requerir que los firmantes verifiquen su correo electrónico con un código de un solo uso. null = heredar del espacio de trabajo/empresa."
                      },
                      "disable_guided_navigation": {
                        "type": "boolean",
                        "nullable": true,
                        "description": "Deshabilitar el desplazamiento automático al siguiente campo obligatorio durante la firma. Se hereda del espacio de trabajo o la empresa si no se establece."
                      },
                      "allow_presigning_download": {
                        "type": "boolean",
                        "nullable": true,
                        "description": "Permitir a los firmantes descargar el documento original antes de firmar. Se hereda de la configuración del espacio de trabajo o la empresa cuando es null."
                      },
                      "show_qr_code": {
                        "type": "boolean",
                        "nullable": true,
                        "description": "Muestra un código QR en la página de firma que permite a los firmantes continuar desde su teléfono. Hereda la configuración del espacio de trabajo o de la empresa cuando es null."
                      }
                    }
                  },
                  "document_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "ID de un documento subido previamente (mutuamente excluyente con document). Obténlo llamando primero a POST /documents.",
                    "example": "123e4567-e89b-12d3-a456-426614174000"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Plantilla creada exitosamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de solicitudes: 120 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Template"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "createTemplate",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.templates.createTemplate({\n    name: \"Employment Contract Template\",\n    document: \"JVBERi0xLjQKJeLjz9MKMyAwIG9iago8PC9UeXBlIC9QYWdlCi9QYXJlbnQgMSAwIFIKL1Jlc291c...\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/templates/{id}": {
      "get": {
        "summary": "Obtener Plantilla",
        "description": "Recupera una plantilla específica por ID",
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Plantilla recuperada exitosamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de solicitudes: 200 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Template"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "getTemplate",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.templates.getTemplate({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      },
      "patch": {
        "summary": "Actualizar Plantilla Parcialmente",
        "description": "Actualiza las propiedades de la plantilla, un solo usuario, O un solo campo. No se pueden mezclar múltiples tipos de entidad en una sola solicitud. Usa PUT para actualizaciones integrales que incluyan usuarios, campos y recordatorios.",
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "object",
                    "description": "Actualizar propiedades de la plantilla",
                    "properties": {
                      "name": {
                        "type": "string",
                        "maxLength": 255,
                        "description": "Nombre de la plantilla"
                      },
                      "description": {
                        "type": "string",
                        "description": "Descripción de la plantilla"
                      },
                      "document": {
                        "type": "string",
                        "format": "byte",
                        "description": "PDF o DOCX codificado en Base64 para reemplazar el documento. Los archivos DOCX se convierten automáticamente a PDF. Tamaño máximo: 20MB"
                      },
                      "expiration_hours": {
                        "type": "integer",
                        "minimum": 1,
                        "description": "Horas hasta la expiración"
                      },
                      "settings": {
                        "type": "object",
                        "properties": {
                          "allow_editing_before_sending": {
                            "type": "boolean"
                          },
                          "attach_pdf_on_finish": {
                            "type": "boolean"
                          },
                          "allow_download": {
                            "type": "boolean"
                          },
                          "hand_drawn_only": {
                            "type": "boolean"
                          },
                          "require_otp_verification": {
                            "type": "boolean",
                            "nullable": true
                          },
                          "disable_guided_navigation": {
                            "type": "boolean",
                            "nullable": true
                          },
                          "allow_presigning_download": {
                            "type": "boolean",
                            "nullable": true,
                            "description": "Permite a los firmantes descargar el documento original antes de firmar. Hereda la configuración del espacio de trabajo o de la empresa cuando es null."
                          },
                          "show_qr_code": {
                            "type": "boolean",
                            "nullable": true,
                            "description": "Muestra un código QR en la página de firma que permite a los firmantes continuar desde su teléfono. Hereda la configuración del espacio de trabajo o de la empresa cuando es null."
                          }
                        }
                      }
                    }
                  },
                  {
                    "type": "object",
                    "description": "Actualizar o crear un solo usuario",
                    "required": [
                      "user"
                    ],
                    "properties": {
                      "user": {
                        "type": "object",
                        "required": [
                          "first_name",
                          "email",
                          "designation",
                          "order"
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid",
                            "description": "Inclúyelo para actualizar un usuario existente, omítelo para crear uno nuevo"
                          },
                          "first_name": {
                            "type": "string",
                            "maxLength": 255
                          },
                          "last_name": {
                            "type": "string",
                            "maxLength": 255,
                            "description": "Opcional, pero requerido si se usan las variables prellenadas full_name o last_name"
                          },
                          "email": {
                            "type": "string",
                            "format": "email"
                          },
                          "designation": {
                            "type": "string",
                            "enum": [
                              "Signer",
                              "Approver",
                              "CC"
                            ]
                          },
                          "order": {
                            "type": "integer",
                            "minimum": 1
                          },
                          "phone_number": {
                            "type": "string"
                          },
                          "street_address": {
                            "type": "string"
                          },
                          "city": {
                            "type": "string"
                          },
                          "state_province": {
                            "type": "string"
                          },
                          "postal_code": {
                            "type": "string"
                          },
                          "country": {
                            "type": "string"
                          },
                          "title": {
                            "type": "string"
                          },
                          "company": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  },
                  {
                    "type": "object",
                    "description": "Actualizar o crear un solo campo",
                    "required": [
                      "field"
                    ],
                    "properties": {
                      "field": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid",
                            "description": "Inclúyelo para actualizar un campo existente, omítelo para crear uno nuevo"
                          },
                          "type": {
                            "type": "string",
                            "enum": [
                              "text",
                              "signature",
                              "date",
                              "checkbox",
                              "initial",
                              "initials",
                              "dropdown",
                              "radio_buttons",
                              "textarea",
                              "text_area",
                              "url",
                              "file",
                              "stamp",
                              "approval_signature",
                              "approval_checkmark",
                              "approval_date"
                            ],
                            "description": "Tipo de campo. Acepta 'initial' o 'initials', 'textarea' o 'text_area'. Requerido para campos nuevos. Los campos url son de solo lectura automáticamente. Los campos file permiten a los firmantes subir archivos adjuntos (imágenes/PDF). Los campos stamp muestran una imagen preconfigurada."
                          },
                          "x": {
                            "type": "number",
                            "description": "Posición X en el documento. Requerido para campos nuevos."
                          },
                          "y": {
                            "type": "number",
                            "description": "Posición Y en el documento. Requerido para campos nuevos."
                          },
                          "width": {
                            "type": "number",
                            "description": "Ancho del campo. Requerido para campos nuevos."
                          },
                          "height": {
                            "type": "number",
                            "description": "Alto del campo. Requerido para campos nuevos."
                          },
                          "page": {
                            "type": "integer",
                            "minimum": 1,
                            "description": "Número de página (indexado desde 1). Requerido para campos nuevos."
                          },
                          "required": {
                            "type": "boolean",
                            "description": "Si el campo es obligatorio"
                          },
                          "assigned_to_user_id": {
                            "type": "string",
                            "format": "uuid",
                            "nullable": true,
                            "description": "ID del usuario de la plantilla al que se asigna el campo"
                          },
                          "variable_name": {
                            "type": "string",
                            "description": "Nombre de variable para el mapeo de datos prellenados"
                          },
                          "variable_defined_name": {
                            "type": "string",
                            "maxLength": 100,
                            "nullable": true,
                            "description": "Nombre legible personalizado para la definición del campo. Se puede usar como alternativa a variable_name para apuntar a campos en la creación basada en plantillas."
                          },
                          "options": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "description": "Opciones para campos desplegables"
                          },
                          "format_rules": {
                            "type": "object",
                            "description": "Reglas de formato (p. ej., formato de fecha, urlDisplayText para campos url, acceptedFileTypes para campos file)"
                          },
                          "multi_group_id": {
                            "type": "string",
                            "format": "uuid",
                            "description": "ID de grupo para grupos de botones de radio"
                          },
                          "default_to_signing_date": {
                            "type": "boolean",
                            "description": "Para campos de fecha, usar la fecha de firma como valor predeterminado"
                          },
                          "read_only": {
                            "type": "boolean",
                            "description": "Si el campo es de solo lectura (automáticamente true para campos url)"
                          },
                          "read_only_value": {
                            "type": "string",
                            "description": "Valor estático para campos de solo lectura. Para campos url, esta es la URL a la que se enlaza."
                          }
                        }
                      }
                    }
                  }
                ]
              },
              "examples": {
                "update-properties": {
                  "summary": "Actualizar propiedades",
                  "value": {
                    "name": "Updated Template Name",
                    "expiration_hours": 72
                  }
                },
                "create-url-field": {
                  "summary": "Crear campo URL",
                  "value": {
                    "field": {
                      "type": "url",
                      "x": 100,
                      "y": 200,
                      "width": 150,
                      "height": 30,
                      "page": 1,
                      "read_only_value": "https://example.com/terms",
                      "format_rules": {
                        "urlDisplayText": "View Terms & Conditions"
                      }
                    }
                  }
                },
                "create-file-field": {
                  "summary": "Crear campo de subida de archivo",
                  "value": {
                    "field": {
                      "type": "file",
                      "x": 100,
                      "y": 300,
                      "width": 200,
                      "height": 40,
                      "page": 1,
                      "required": true,
                      "format_rules": {
                        "acceptedFileTypes": "image_and_pdf"
                      }
                    }
                  }
                },
                "update-field": {
                  "summary": "Actualizar campo existente",
                  "value": {
                    "field": {
                      "id": "field123-e89b-12d3-a456-426614174000",
                      "x": 120,
                      "y": 220
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Plantilla actualizada parcialmente con éxito",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de solicitudes: 120 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplatePatchResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "patchTemplate",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.templates.patchTemplate({\n    id: \"id\",\n    body: {\n        name: \"Updated Template Name\",\n        expiration_hours: 72\n    }\n});\nconsole.log(response);"
          }
        ]
      },
      "put": {
        "summary": "Actualización Integral de Plantilla",
        "description": "Actualización integral de la plantilla, incluyendo propiedades, usuarios, campos y recordatorios. Admite la eliminación de usuarios con reasignación o eliminación de campos. Todas las secciones son opcionales, pero se debe proporcionar al menos una.",
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "template_properties": {
                    "type": "object",
                    "description": "Actualizar los metadatos y la configuración de la plantilla",
                    "properties": {
                      "name": {
                        "type": "string",
                        "maxLength": 255
                      },
                      "description": {
                        "type": "string"
                      },
                      "document": {
                        "type": "string",
                        "format": "byte",
                        "description": "PDF o DOCX codificado en Base64 para reemplazar el documento. Los archivos DOCX se convierten automáticamente a PDF. Tamaño máximo: 20MB"
                      },
                      "expiration_hours": {
                        "type": "integer",
                        "minimum": 1
                      },
                      "settings": {
                        "type": "object",
                        "properties": {
                          "allow_editing_before_sending": {
                            "type": "boolean"
                          },
                          "attach_pdf_on_finish": {
                            "type": "boolean"
                          },
                          "allow_download": {
                            "type": "boolean"
                          },
                          "hand_drawn_only": {
                            "type": "boolean"
                          },
                          "require_otp_verification": {
                            "type": "boolean",
                            "nullable": true
                          },
                          "disable_guided_navigation": {
                            "type": "boolean",
                            "nullable": true
                          },
                          "allow_presigning_download": {
                            "type": "boolean",
                            "nullable": true,
                            "description": "Permite a los firmantes descargar el documento original antes de firmar. Hereda la configuración del espacio de trabajo o de la empresa cuando es null."
                          },
                          "show_qr_code": {
                            "type": "boolean",
                            "nullable": true,
                            "description": "Muestra un código QR en la página de firma que permite a los firmantes continuar desde su teléfono. Hereda la configuración del espacio de trabajo o de la empresa cuando es null."
                          }
                        }
                      }
                    }
                  },
                  "users": {
                    "type": "array",
                    "description": "Insertar o actualizar usuarios (incluye id para actualizar, omítelo para crear)",
                    "items": {
                      "type": "object",
                      "required": [
                        "first_name",
                        "email",
                        "designation",
                        "order"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid",
                          "description": "Omítelo para usuarios nuevos"
                        },
                        "first_name": {
                          "type": "string"
                        },
                        "last_name": {
                          "type": "string",
                          "description": "Opcional, pero requerido si se usan las variables prellenadas full_name o last_name"
                        },
                        "email": {
                          "type": "string",
                          "format": "email"
                        },
                        "designation": {
                          "type": "string",
                          "enum": [
                            "Signer",
                            "Approver",
                            "CC"
                          ]
                        },
                        "order": {
                          "type": "integer",
                          "minimum": 1
                        },
                        "phone_number": {
                          "type": "string"
                        },
                        "street_address": {
                          "type": "string"
                        },
                        "city": {
                          "type": "string"
                        },
                        "state_province": {
                          "type": "string"
                        },
                        "postal_code": {
                          "type": "string"
                        },
                        "country": {
                          "type": "string"
                        },
                        "title": {
                          "type": "string"
                        },
                        "company": {
                          "type": "string"
                        }
                      }
                    }
                  },
                  "force_remove_conditions": {
                    "type": "boolean",
                    "default": false,
                    "description": "Al eliminar usuarios cuyos campos son referenciados por condiciones en otros campos: si es true, elimina automáticamente las referencias de condición; si es false (predeterminado), la solicitud será rechazada con un error."
                  },
                  "deleted_users": {
                    "type": "array",
                    "description": "Usuarios a eliminar con estrategia de manejo de campos",
                    "items": {
                      "type": "object",
                      "required": [
                        "user_id",
                        "field_action"
                      ],
                      "properties": {
                        "user_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "field_action": {
                          "type": "string",
                          "enum": [
                            "delete",
                            "reassign"
                          ],
                          "description": "Qué hacer con los campos asignados a este usuario"
                        },
                        "reassign_to_user_id": {
                          "type": "string",
                          "format": "uuid",
                          "description": "Requerido cuando field_action es 'reassign'. El usuario destino debe tener la misma designación."
                        }
                      }
                    }
                  },
                  "fields": {
                    "type": "array",
                    "description": "Crea o actualiza campos (incluye id para actualizar, omítelo para crear)",
                    "items": {
                      "type": "object",
                      "required": [
                        "type",
                        "x",
                        "y",
                        "width",
                        "height",
                        "page"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid",
                          "description": "Omitir para campos nuevos"
                        },
                        "type": {
                          "type": "string",
                          "enum": [
                            "signature",
                            "text",
                            "date",
                            "checkbox",
                            "dropdown",
                            "approval_signature",
                            "approval_checkmark",
                            "approval_date"
                          ]
                        },
                        "x": {
                          "type": "number",
                          "minimum": 0,
                          "maximum": 100,
                          "description": "Posición X como porcentaje"
                        },
                        "y": {
                          "type": "number",
                          "minimum": 0,
                          "maximum": 100,
                          "description": "Posición Y como porcentaje"
                        },
                        "width": {
                          "type": "number",
                          "minimum": 0,
                          "maximum": 100
                        },
                        "height": {
                          "type": "number",
                          "minimum": 0,
                          "maximum": 100
                        },
                        "page": {
                          "type": "integer",
                          "minimum": 1
                        },
                        "required": {
                          "type": "boolean",
                          "default": false
                        },
                        "assigned_to_user_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "options": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Para campos de tipo desplegable"
                        },
                        "default_to_signing_date": {
                          "type": "boolean",
                          "description": "Para campos de fecha"
                        },
                        "multi_group_id": {
                          "type": "string",
                          "format": "uuid",
                          "description": "ID de grupo para grupos de casillas de verificación/botones de opción mutuamente excluyentes"
                        },
                        "variable_name": {
                          "type": "string"
                        },
                        "variable_defined_name": {
                          "type": "string",
                          "maxLength": 100,
                          "nullable": true,
                          "description": "Nombre de definición de campo personalizado legible para humanos. Se puede usar como alternativa a variable_name para apuntar a campos en la creación basada en plantillas."
                        },
                        "required_conditions": {
                          "$ref": "#/components/schemas/ConditionSet",
                          "nullable": true
                        },
                        "visibility_conditions": {
                          "$ref": "#/components/schemas/ConditionSet",
                          "nullable": true
                        }
                      }
                    }
                  },
                  "reminders": {
                    "type": "array",
                    "description": "Crea o actualiza recordatorios (incluye id para actualizar, omítelo para crear)",
                    "items": {
                      "type": "object",
                      "required": [
                        "hours",
                        "subject",
                        "message"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid",
                          "description": "Omitir para recordatorios nuevos"
                        },
                        "hours": {
                          "type": "integer",
                          "minimum": 1,
                          "description": "Horas después del envío antes del recordatorio"
                        },
                        "all_users": {
                          "type": "boolean",
                          "default": false
                        },
                        "user_id": {
                          "type": "string",
                          "format": "uuid",
                          "description": "Requerido si all_users es false"
                        },
                        "subject": {
                          "type": "string",
                          "maxLength": 255
                        },
                        "message": {
                          "type": "string",
                          "maxLength": 5000
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Plantilla actualizada correctamente. Devuelve la plantilla completa con todas sus relaciones.",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de solicitudes: 120 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Template"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "updateTemplate",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.templates.updateTemplate({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      },
      "delete": {
        "summary": "Eliminar una plantilla",
        "description": "Elimina de forma parcial (soft delete) una plantilla por ID. Esto marca la plantilla como eliminada pero conserva los datos.",
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID de la plantilla",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Plantilla eliminada correctamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de solicitudes: 120 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solicitudes restantes en la ventana actual"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Marca de tiempo Unix cuando se restablece el límite de solicitudes"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageResponse"
                },
                "example": {
                  "message": "Template deleted successfully"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "deleteTemplate",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.templates.deleteTemplate({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/templates/{id}/users": {
      "get": {
        "summary": "Obtener usuarios de la plantilla",
        "description": "Recupera todos los destinatarios/usuarios asociados con una plantilla específica",
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID de la plantilla",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Usuarios de la plantilla recuperados correctamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de solicitudes: 200 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solicitudes restantes en la ventana actual"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Marca de tiempo Unix cuando se restablece el límite de solicitudes"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateUserListResponse"
                },
                "example": {
                  "results": [
                    {
                      "id": "abc12345-e89b-12d3-a456-426614174000",
                      "name": "John Doe",
                      "email": "john@example.com",
                      "first_name": "John",
                      "last_name": "Doe",
                      "designation": "Signer",
                      "order": 1,
                      "phone_number": null,
                      "street_address": null,
                      "city": null,
                      "state_province": null,
                      "postal_code": null,
                      "country": null,
                      "title": null,
                      "company": null,
                      "required_fields": [
                        "email",
                        "first_name"
                      ],
                      "missing_fields": [],
                      "required_read_only_fields": [],
                      "ready_to_send": true
                    },
                    {
                      "id": "def67890-e89b-12d3-a456-426614174000",
                      "name": null,
                      "email": null,
                      "first_name": null,
                      "last_name": null,
                      "designation": "Signer",
                      "order": 2,
                      "phone_number": null,
                      "street_address": null,
                      "city": null,
                      "state_province": null,
                      "postal_code": null,
                      "country": null,
                      "title": null,
                      "company": null,
                      "required_fields": [
                        "email",
                        "first_name",
                        "phone_number"
                      ],
                      "missing_fields": [
                        "email",
                        "first_name",
                        "phone_number"
                      ],
                      "required_read_only_fields": [
                        {
                          "variable_name": "contract_date",
                          "field_type": "date"
                        }
                      ],
                      "ready_to_send": false
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "listTemplateUsers",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.templates.listTemplateUsers({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/templates/{id}/fields": {
      "get": {
        "summary": "Obtener campos de la plantilla",
        "description": "Recupera todos los campos configurados para una plantilla específica",
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID de la plantilla",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Campos de la plantilla recuperados correctamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de solicitudes: 200 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solicitudes restantes en la ventana actual"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Marca de tiempo Unix cuando se restablece el límite de solicitudes"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateFieldListResponse"
                },
                "example": {
                  "results": [
                    {
                      "id": "field123-e89b-12d3-a456-426614174000",
                      "type": "signature",
                      "required": true,
                      "recipient_id": "user123-uuid",
                      "variable_name": null,
                      "position": {
                        "x": 100,
                        "y": 200,
                        "width": 200,
                        "height": 50
                      },
                      "page_number": 1,
                      "dropdown_options": null,
                      "multi_group_id": null,
                      "date_signing_default": false,
                      "format_rules": null,
                      "validation_rules": null,
                      "read_only": false,
                      "read_only_value": null
                    },
                    {
                      "id": "field456-e89b-12d3-a456-426614174000",
                      "type": "date",
                      "required": true,
                      "recipient_id": "user123-uuid",
                      "variable_name": null,
                      "position": {
                        "x": 100,
                        "y": 250,
                        "width": 150,
                        "height": 30
                      },
                      "page_number": 1,
                      "dropdown_options": null,
                      "multi_group_id": null,
                      "date_signing_default": true,
                      "format_rules": {
                        "date_format": "MM/DD/YYYY"
                      },
                      "validation_rules": null,
                      "read_only": false,
                      "read_only_value": null
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "listTemplateFields",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.templates.listTemplateFields({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/templates/{id}/reminders": {
      "get": {
        "summary": "Obtener recordatorios de la plantilla",
        "description": "Recupera todos los recordatorios configurados para una plantilla específica",
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID de la plantilla",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Recordatorios de la plantilla recuperados correctamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de solicitudes: 200 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solicitudes restantes en la ventana actual"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Marca de tiempo Unix cuando se restablece el límite de solicitudes"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Reminder"
                  }
                },
                "example": [
                  {
                    "id": "remind123-e89b-12d3-a456-426614174000",
                    "hours": 24,
                    "subject": "Reminder: Please sign the document",
                    "message": "This is a friendly reminder to complete your signature.",
                    "all_users": true,
                    "template_user_id": null,
                    "created_date": "2024-01-15T10:30:00Z",
                    "updated_date": "2024-01-15T10:30:00Z"
                  }
                ]
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "listTemplateReminders",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.templates.listTemplateReminders({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/templates/{id}/replace-document": {
      "post": {
        "summary": "Reemplazar documento de la plantilla",
        "description": "Reemplaza el documento PDF de una plantilla existente conservando todas las ubicaciones de los campos. El documento de reemplazo debe tener el mismo número de páginas y dimensiones de página coincidentes (con una tolerancia de 1pt) que el original.",
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID de la plantilla"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "document"
                ],
                "properties": {
                  "document": {
                    "type": "string",
                    "description": "Documento PDF o DOCX codificado en Base64. Los archivos DOCX se convierten automáticamente a PDF."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Documento reemplazado correctamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de solicitudes: 120 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Template"
                }
              }
            }
          },
          "400": {
            "description": "Error de validación (número de páginas no coincide, dimensiones no coinciden, documento inválido)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "replaceTemplateDocument",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.templates.replaceTemplateDocument({\n    id: \"id\",\n    document: \"document\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/templates/{id}/duplicate": {
      "post": {
        "summary": "Duplicar plantilla en solicitud de firma",
        "description": "Crea una nueva solicitud de firma duplicando una plantilla existente, incluyendo todos los campos, usuarios, recordatorios y configuraciones.",
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID de la plantilla a duplicar"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Nombre personalizado para la nueva solicitud de firma (por defecto, el nombre de la plantilla)"
                  }
                }
              },
              "example": {
                "name": "Q4 2025 Contract"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Plantilla duplicada correctamente en una nueva solicitud de firma",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de solicitudes: 120 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateDuplicateResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "description": "La plantilla pertenece a un espacio de trabajo diferente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "duplicateTemplate",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.templates.duplicateTemplate({\n    id: \"id\",\n    name: \"Q4 2025 Contract\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/signing-requests": {
      "get": {
        "summary": "Listar Solicitudes de Firma",
        "description": "Recupera una lista paginada de solicitudes de firma",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            },
            "description": "Número de página"
          },
          {
            "name": "page_size",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "description": "Elementos por página"
          },
          {
            "name": "name",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filtrar por nombre de la solicitud de firma (coincidencia parcial, sin distinción entre mayúsculas y minúsculas)"
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "not_sent",
                "in_progress",
                "finished",
                "cancelled",
                "declined",
                "deleted",
                "expired"
              ]
            },
            "description": "Filtrar por estado de la solicitud de firma. Admite múltiples valores separados por comas.\n\n**Estados disponibles:**\n- `not_sent`: Solicitud creada pero aún no enviada a los firmantes\n- `in_progress`: Enviada a los firmantes pero no completada, cancelada, rechazada ni expirada\n- `finished`: Todos los firmantes han completado\n- `cancelled`: La solicitud fue cancelada por el remitente\n- `declined`: Un firmante rechazó firmar (la solicitud se detiene)\n- `deleted`: Registros eliminados de forma parcial (normalmente ocultos)\n- `expired`: Enviada pero pasado el tiempo de expiración (sent_on + expiration_hours < now)\n\n**Ejemplo:** `?status=in_progress,expired`\n\n**Nota:** El estado `expired` usa filtrado posterior, lo que puede tener implicaciones de rendimiento en conjuntos de datos grandes."
          },
          {
            "name": "created_after",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Filtrar solicitudes de firma creadas después de esta fecha (formato ISO 8601)"
          },
          {
            "name": "created_before",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Filtra las solicitudes de firma creadas antes de esta fecha (formato ISO 8601)"
          },
          {
            "name": "signer_email",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filtra por dirección de email del firmante (coincidencia exacta)"
          },
          {
            "name": "signer_name",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filtra por nombre del firmante (coincidencia parcial, sin distinguir mayúsculas/minúsculas)"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "name",
                "created_on",
                "expiration_hours",
                "sent_on",
                "finished_on"
              ],
              "default": "created_on"
            },
            "description": "Campo por el que ordenar"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Orden de clasificación"
          }
        ],
        "responses": {
          "200": {
            "description": "Solicitudes de firma obtenidas correctamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 200 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SigningRequestListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "listSigningRequests",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signingRequests.listSigningRequests();\nconsole.log(response);"
          }
        ]
      },
      "post": {
        "summary": "Crear Solicitud de Firma",
        "description": "Crea una nueva solicitud de firma ya sea a partir de un documento PDF (basado en documento) o a partir de una plantilla existente (basado en plantilla). Para la creación basada en documento, allow_editing_before_sending se establece automáticamente en true. Para la creación basada en plantilla, las propiedades se heredan de la plantilla y se pueden sobrescribir.\n\n**Patrón de ID Temporal**: Para la creación basada en documento, puedes referenciar destinatarios antes de que se creen usando IDs temporales (formato: 'temp_X' donde X es cualquier identificador, por ejemplo, 'temp_1', 'temp_alice'). Usa estos IDs temporales en recipient.id, field.recipient_id y reminder.recipient_id. La API valida todas las referencias y mapea automáticamente los IDs temporales a UUID reales después de que se crean los destinatarios. La respuesta contiene solo UUID reales.\n\n**Validación de ID Temporal**: Los IDs temporales deben comenzar con 'temp_', ser únicos entre todos los destinatarios de la solicitud, y todas las referencias de field/reminder deben apuntar a destinatarios definidos en la misma solicitud. Un formato inválido, IDs duplicados o referencias de destinatario faltantes devuelven un error 400 con mensajes de validación detallados.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/PatchSigningRequestBody"
        },
        "responses": {
          "201": {
            "description": "Solicitud de firma creada correctamente. La respuesta puede incluir un array 'warnings' con advertencias de validación de formato de email (no bloqueantes).",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 120 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SigningRequestCreateResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError",
            "description": "Entrada inválida: debes proporcionar 'document' o 'template_id', no ambos. El documento debe ser un PDF válido codificado en base64 de menos de 20MB. La plantilla debe existir y pertenecer al espacio de trabajo."
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "description": "Plantilla no encontrada o no pertenece al espacio de trabajo",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "createSigningRequest",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signingRequests.createSigningRequest({\n    template_id: \"template_id\",\n    name: \"Updated Contract Name\",\n    expiration_hours: 72\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/signing-requests/create-and-send": {
      "post": {
        "summary": "Crear y Enviar Solicitud de Firma (Atómico)",
        "description": "Crea y envía inmediatamente una solicitud de firma en una única operación atómica. Este endpoint combina la funcionalidad de POST /signing-requests y POST /signing-requests/{id}/send.\n\n**Beneficios Clave:**\n- Una sola llamada a la API en lugar de dos solicitudes separadas\n- Valida todos los requisitos de envío ANTES de crear la solicitud de firma\n- Deducción de créditos atómica: solo cobra si todo tiene éxito\n- Devuelve status: 'sent' inmediatamente con los detalles del primer firmante\n- Más eficiente (ahorra 1 llamada a la API + tiempo de ida y vuelta)\n\n**Validación:**\n- Todas las validaciones de creación estándar (document/template, recipients, fields)\n- Validaciones de envío adicionales:\n  - Todos los firmantes deben tener first_name y un email válido\n  - Los campos de solo lectura requeridos deben tener final_value completado\n  - Los campos de datos prellenados (variable_name) deben tener los datos de usuario correspondientes\n  - La empresa debe tener créditos suficientes (≥1)\n\n**Atomicidad:**\n- Si alguna validación falla, no se crea nada\n- El crédito solo se deduce después de una creación exitosa y antes del envío del email\n- Si el envío del email falla después de la creación, la solicitud de firma permanece en estado 'draft' y el crédito NO se deduce\n\n**Patrón de ID Temporal:** Para la creación basada en documento, usa IDs temporales (formato: 'temp_X') para referenciar destinatarios antes de la creación. La API valida todas las referencias y mapea automáticamente los IDs temporales a UUID reales.\n\n**Límite de Tasa:** 120 solicitudes/minuto (igual que las operaciones de escritura)",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Nombre de la solicitud de firma",
                    "example": "Employment Contract - John Doe"
                  },
                  "description": {
                    "type": "string",
                    "description": "Descripción de la solicitud de firma",
                    "example": "Full-time employment contract for Software Engineer position"
                  },
                  "document": {
                    "type": "string",
                    "format": "byte",
                    "description": "Documento PDF o DOCX codificado en base64 (mutuamente excluyente con template_id y document_id). Los archivos DOCX se convierten automáticamente a PDF. Tamaño máximo: 50MB.",
                    "example": "JVBERi0xLjQKJeLjz9MKMyAwIG9iago8PC9UeXBlIC9QYWdlCi9QYXJlbnQgMSAwIFIKL1Jlc291c..."
                  },
                  "template_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "ID de la plantilla a usar (mutuamente excluyente con document y document_id)",
                    "example": "123e4567-e89b-12d3-a456-426614174000"
                  },
                  "expiration_hours": {
                    "type": "integer",
                    "minimum": 1,
                    "default": 168,
                    "description": "Horas hasta que expira la solicitud de firma (por defecto: 168 = 7 días)",
                    "example": 168
                  },
                  "recipients": {
                    "type": "array",
                    "description": "Array de destinatarios. Al menos uno debe ser un Firmante. Para creación basada en documento: obligatorio. Para creación basada en plantilla: opcional (usa los destinatarios de la plantilla si se omite). Usa template_user_id (preferido) u order (alternativa) para hacer coincidir con los usuarios de la plantilla.",
                    "minItems": 1,
                    "items": {
                      "$ref": "#/components/schemas/Recipient"
                    }
                  },
                  "fields": {
                    "type": "array",
                    "description": "Array de campos a completar (solo para creación basada en documento)",
                    "items": {
                      "type": "object",
                      "required": [
                        "type",
                        "page",
                        "x",
                        "y"
                      ],
                      "properties": {
                        "recipient_id": {
                          "type": "string",
                          "description": "ID temporal o UUID del destinatario asignado a este campo",
                          "example": "temp_signer_1"
                        },
                        "type": {
                          "type": "string",
                          "enum": [
                            "signature",
                            "initial",
                            "text",
                            "date",
                            "checkbox",
                            "dropdown",
                            "radio_buttons",
                            "text_area",
                            "url",
                            "file",
                            "stamp",
                            "approval_signature",
                            "approval_checkmark",
                            "approval_date"
                          ],
                          "description": "Tipo de campo. Acepta alias: \"initials\" (normalizado a \"initial\"), \"textarea\" (normalizado a \"text_area\"), \"radio\" (normalizado a \"radio_buttons\").",
                          "example": "signature"
                        },
                        "page": {
                          "type": "integer",
                          "minimum": 1,
                          "description": "Número de página del PDF (indexado desde 1)",
                          "example": 1
                        },
                        "x": {
                          "type": "number",
                          "description": "Coordenada X en la página",
                          "example": 100
                        },
                        "y": {
                          "type": "number",
                          "description": "Coordenada Y en la página",
                          "example": 200
                        },
                        "width": {
                          "type": "number",
                          "default": 200,
                          "example": 200
                        },
                        "height": {
                          "type": "number",
                          "default": 50,
                          "example": 50
                        },
                        "variable_name": {
                          "type": "string",
                          "description": "Nombre de variable para datos precargados (por ejemplo, 'phone_number', 'company'). Si se establece, el campo correspondiente del destinatario debe estar completado.",
                          "enum": [
                            "first_name",
                            "last_name",
                            "full_name",
                            "email",
                            "phone_number",
                            "street_address",
                            "city",
                            "state_province",
                            "postal_code",
                            "country",
                            "title",
                            "company"
                          ],
                          "example": "phone_number"
                        },
                        "variable_defined_name": {
                          "type": "string",
                          "maxLength": 100,
                          "nullable": true,
                          "description": "Nombre legible del campo personalizado. Se puede usar como alternativa a variable_name para apuntar a campos en la creación basada en plantilla."
                        },
                        "required": {
                          "type": "boolean",
                          "default": false,
                          "description": "Si el campo es obligatorio"
                        },
                        "read_only": {
                          "type": "boolean",
                          "default": false,
                          "description": "Si el campo es de solo lectura (precargado)"
                        },
                        "final_value": {
                          "type": "string",
                          "description": "Valor precargado para campos de solo lectura (obligatorio si read_only=true y required=true)",
                          "example": "Software Engineer"
                        },
                        "background_color": {
                          "type": "string",
                          "nullable": true,
                          "pattern": "^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$",
                          "description": "Color de fondo en hexadecimal (por ejemplo, '#FFFDE7')",
                          "example": "#FFFDE7"
                        },
                        "dropdown_options": {
                          "description": "Opciones para campos desplegables. Obligatorio cuando type es \"dropdown\".",
                          "example": [
                            "Option A",
                            "Option B",
                            "Option C"
                          ],
                          "oneOf": [
                            {
                              "type": "array",
                              "items": {
                                "type": "string"
                              }
                            },
                            {
                              "type": "object"
                            }
                          ]
                        }
                      }
                    }
                  },
                  "anchor_tags": {
                    "type": "array",
                    "maxItems": 100,
                    "items": {
                      "$ref": "#/components/schemas/AnchorTag"
                    },
                    "description": "Etiquetas de anclaje para la colocación automática de campos. Se localizan marcadores de texto en el PDF y se convierten en campos posicionados. El texto de anclaje se elimina del PDF después del procesamiento. Los campos creados a partir de etiquetas de anclaje se agregan junto a cualquier campo especificado manualmente. Solo disponible para creación basada en documento (no para creación basada en plantilla)."
                  },
                  "reminders": {
                    "type": "array",
                    "description": "Array de configuraciones de recordatorios",
                    "items": {
                      "type": "object",
                      "required": [
                        "hours_before_expiration"
                      ],
                      "properties": {
                        "hours_before_expiration": {
                          "type": "integer",
                          "minimum": 1,
                          "description": "Horas antes de la expiración para enviar el recordatorio",
                          "example": 24
                        }
                      }
                    }
                  },
                  "settings": {
                    "type": "object",
                    "description": "Configuración de la solicitud de firma",
                    "properties": {
                      "use_signing_order": {
                        "type": "boolean",
                        "default": true,
                        "description": "Aplica el orden de firma según recipient.order. Cuando es false, todos los firmantes reciben el documento simultáneamente."
                      },
                      "allow_download": {
                        "type": "boolean",
                        "default": true,
                        "description": "Permite a los destinatarios descargar el documento"
                      },
                      "attach_pdf_on_finish": {
                        "type": "boolean",
                        "default": true,
                        "description": "Adjunta el PDF completado al correo de finalización"
                      },
                      "send_signing_email": {
                        "type": "boolean",
                        "default": true,
                        "description": "Envía notificación por correo a los firmantes"
                      },
                      "send_finish_email": {
                        "type": "boolean",
                        "default": true,
                        "description": "Envía un correo cuando se completan todas las firmas"
                      },
                      "send_expiration_email": {
                        "type": "boolean",
                        "default": true,
                        "description": "Envía un correo cuando expira la solicitud"
                      },
                      "send_cancellation_email": {
                        "type": "boolean",
                        "default": true,
                        "description": "Envía un correo cuando se cancela la solicitud"
                      },
                      "hand_drawn_only": {
                        "type": "boolean",
                        "default": false,
                        "description": "Exige a los firmantes dibujar su firma a mano en lugar de usar firmas escritas"
                      },
                      "identity_editable_fields": {
                        "type": "array",
                        "nullable": true,
                        "items": {
                          "type": "string",
                          "enum": [
                            "name",
                            "company",
                            "title",
                            "phone",
                            "address"
                          ]
                        },
                        "description": "Campos de identidad que los firmantes pueden editar antes de firmar. null = deshabilitado. Cuando se configura, aparece un diálogo de confirmación que permite a los firmantes editar los campos especificados.",
                        "example": [
                          "name",
                          "company"
                        ]
                      },
                      "notify_identity_change_webhook": {
                        "type": "boolean",
                        "default": false,
                        "description": "Envía un evento de webhook cuando un firmante cambia su identidad"
                      },
                      "notify_identity_change_email": {
                        "type": "boolean",
                        "default": false,
                        "description": "Envía notificación por correo cuando un firmante cambia su identidad"
                      }
                    }
                  },
                  "document_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "ID de un documento subido previamente (mutuamente excluyente con document y template_id). Se obtiene llamando primero a POST /documents.",
                    "example": "123e4567-e89b-12d3-a456-426614174000"
                  }
                },
                "oneOf": [
                  {
                    "required": [
                      "document"
                    ]
                  },
                  {
                    "required": [
                      "template_id"
                    ]
                  }
                ]
              },
              "examples": {
                "document-based": {
                  "summary": "Crear y enviar con documento",
                  "value": {
                    "name": "Employment Contract - John Doe",
                    "description": "Contrato de empleo a tiempo completo",
                    "document": "JVBERi0xLjQKJeLjz9MK...",
                    "expiration_hours": 168,
                    "recipients": [
                      {
                        "id": "temp_signer_1",
                        "first_name": "John",
                        "last_name": "Doe",
                        "email": "john.doe@example.com",
                        "designation": "Signer",
                        "order": 1,
                        "phone_number": "+1-555-0123",
                        "company": "Acme Corp",
                        "title": "Ingeniero de Software"
                      }
                    ],
                    "fields": [
                      {
                        "recipient_id": "temp_signer_1",
                        "type": "signature",
                        "page": 1,
                        "x": 100,
                        "y": 500,
                        "width": 200,
                        "height": 50
                      },
                      {
                        "recipient_id": "temp_signer_1",
                        "type": "text",
                        "page": 1,
                        "x": 100,
                        "y": 400,
                        "width": 150,
                        "height": 30,
                        "variable_name": "phone_number",
                        "required": true,
                        "read_only": true
                      }
                    ],
                    "settings": {
                      "use_signing_order": true,
                      "send_signing_email": true
                    }
                  }
                },
                "template-based": {
                  "summary": "Crear y enviar desde plantilla",
                  "value": {
                    "name": "NDA - Jane Smith",
                    "template_id": "123e4567-e89b-12d3-a456-426614174000",
                    "recipients": [
                      {
                        "first_name": "Jane",
                        "last_name": "Smith",
                        "email": "jane.smith@example.com",
                        "designation": "Signer",
                        "order": 1,
                        "company": "Tech Startup Inc"
                      }
                    ],
                    "expiration_hours": 72
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Solicitud de Firma creada y enviada correctamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 120 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateAndSendResponse"
                },
                "example": {
                  "id": "550e8400-e29b-41d4-a716-446655440000",
                  "name": "Employment Contract - John Doe",
                  "description": "Contrato de empleo a tiempo completo",
                  "status": "sent",
                  "document_url": "https://storage.supabase.co/...",
                  "page_count": 3,
                  "expiration_hours": 168,
                  "settings": {
                    "use_signing_order": true,
                    "allow_download": true,
                    "attach_pdf_on_finish": true,
                    "send_signing_email": true,
                    "send_finish_email": true,
                    "send_expiration_email": true,
                    "send_cancellation_email": true,
                    "hand_drawn_only": false
                  },
                  "created_date": "2026-01-12T10:30:00Z",
                  "sent_date": "2026-01-12T10:30:00Z",
                  "template_id": null,
                  "first_signer": {
                    "id": "rec456-e89b-12d3-a456-426614174000",
                    "name": "John Doe",
                    "email": "john.doe@example.com",
                    "signing_link": "https://app.firma.dev/signing/rec456-e89b-12d3-a456-426614174000"
                  },
                  "recipients": [
                    {
                      "id": "rec456-e89b-12d3-a456-426614174000",
                      "first_name": "John",
                      "last_name": "Doe",
                      "name": "John Doe",
                      "email": "john.doe@example.com",
                      "designation": "Signer",
                      "order": 1
                    }
                  ],
                  "fields": [
                    {
                      "id": "field123-e89b-12d3-a456-426614174000",
                      "type": "signature",
                      "page": 1,
                      "x": 100,
                      "y": 500,
                      "width": 200,
                      "height": 50,
                      "required": true,
                      "recipient_id": "rec456-e89b-12d3-a456-426614174000"
                    }
                  ],
                  "credits_remaining": 99
                }
              }
            }
          },
          "400": {
            "description": "Error de validación: entrada inválida o faltan datos obligatorios del firmante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateAndSendValidationError"
                },
                "examples": {
                  "missing-recipient-data": {
                    "value": {
                      "error": "One or more signers are missing required information for sending",
                      "phase": "send_validation",
                      "validation_errors": [
                        {
                          "recipient_index": 1,
                          "recipient_email": "john@example.com",
                          "missing_fields": [
                            "phone_number",
                            "company"
                          ]
                        }
                      ]
                    }
                  },
                  "invalid-document": {
                    "value": {
                      "error": "Document must be valid base64-encoded PDF",
                      "phase": "create_validation"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "402": {
            "description": "Créditos insuficientes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientCreditsError"
                }
              }
            }
          },
          "404": {
            "description": "Plantilla no encontrada o no pertenece al espacio de trabajo",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "La dirección de correo del destinatario está suprimida (rebotó anteriormente o fue marcada como spam) y no se le puede enviar",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnprocessableEntityError"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          },
          "500": {
            "description": "Error inesperado del servidor. Cualquier Solicitud de Firma creada parcialmente se revierte, por lo que no queda ningún borrador. Los errores del paso de envío accionables por el cliente devuelven 400, 402 o 422 en su lugar.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "createAndSendSigningRequest",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signingRequests.createAndSendSigningRequest({\n    \"name\": \"Employment Contract - John Doe\",\n    \"description\": \"Full-time employment contract\",\n    \"document\": \"JVBERi0xLjQKJeLjz9MK...\",\n    \"expiration_hours\": 168,\n    \"recipients\": [\n        {\n            \"id\": \"temp_signer_1\",\n            \"first_name\": \"John\",\n            \"last_name\": \"Doe\",\n            \"email\": \"john.doe@example.com\",\n            \"designation\": \"Signer\",\n            \"order\": 1,\n            \"phone_number\": \"+1-555-0123\",\n            \"company\": \"Acme Corp\",\n            \"title\": \"Software Engineer\"\n        }\n    ],\n    \"fields\": [\n        {\n            \"recipient_id\": \"temp_signer_1\",\n            \"type\": \"signature\",\n            \"page\": 1,\n            \"x\": 100,\n            \"y\": 500,\n            \"width\": 200,\n            \"height\": 50\n        },\n        {\n            \"recipient_id\": \"temp_signer_1\",\n            \"type\": \"text\",\n            \"page\": 1,\n            \"x\": 100,\n            \"y\": 400,\n            \"width\": 150,\n            \"height\": 30,\n            \"variable_name\": \"phone_number\",\n            \"required\": true,\n            \"read_only\": true\n        }\n    ],\n    \"settings\": {\n        \"use_signing_order\": true,\n        \"send_signing_email\": true\n    }\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/signing-requests/{id}": {
      "get": {
        "summary": "Obtener Solicitud de Firma",
        "description": "Recupera una Solicitud de Firma específica por ID",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Solicitud de Firma recuperada correctamente. Devuelve una estructura anidada detallada con status como un objeto y las marcas de tiempo agrupadas.",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 200 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SigningRequestDetail"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "getSigningRequest",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signingRequests.getSigningRequest({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      },
      "patch": {
        "summary": "Actualizar Parcialmente una Solicitud de Firma",
        "description": "Actualiza las propiedades de la Solicitud de Firma, un solo destinatario, O un solo campo. No se pueden actualizar varios tipos de entidad en una misma solicitud. No se puede actualizar después de que la Solicitud de Firma haya sido enviada, completada o cancelada.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID de la Solicitud de Firma"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "object",
                    "description": "Actualizar solo las propiedades de la Solicitud de Firma",
                    "properties": {
                      "name": {
                        "type": "string",
                        "maxLength": 255,
                        "description": "Nuevo nombre para la solicitud de firma"
                      },
                      "description": {
                        "type": "string",
                        "description": "Nueva descripción"
                      },
                      "document": {
                        "type": "string",
                        "format": "byte",
                        "description": "Reemplaza el documento con un nuevo PDF codificado en base64. El número de páginas se extraerá automáticamente."
                      },
                      "expiration_hours": {
                        "type": "integer",
                        "minimum": 1,
                        "description": "Nuevas horas de expiración"
                      },
                      "settings": {
                        "$ref": "#/components/schemas/SigningRequestSettings",
                        "description": "Actualizar configuración"
                      }
                    }
                  },
                  {
                    "type": "object",
                    "required": [
                      "recipient"
                    ],
                    "description": "Crea o actualiza un solo destinatario",
                    "properties": {
                      "recipient": {
                        "$ref": "#/components/schemas/Recipient",
                        "description": "Destinatario a crear (omite id) o actualizar (incluye id). Al actualizar first_name o last_name, el campo name se reconstruye automáticamente usando los valores existentes de la base de datos para cualquier campo no proporcionado. Resultado: 'Nombre Apellido' si ambos existen, 'Nombre' si solo existe first_name."
                      }
                    }
                  },
                  {
                    "type": "object",
                    "required": [
                      "field"
                    ],
                    "description": "Crea o actualiza un solo campo",
                    "properties": {
                      "field": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid",
                            "description": "Inclúyelo para actualizar un campo existente, omítelo para crear uno nuevo"
                          },
                          "type": {
                            "type": "string",
                            "enum": [
                              "text",
                              "signature",
                              "date",
                              "checkbox",
                              "initial",
                              "initials",
                              "dropdown",
                              "radio_buttons",
                              "textarea",
                              "text_area",
                              "url",
                              "file",
                              "stamp",
                              "approval_signature",
                              "approval_checkmark",
                              "approval_date"
                            ],
                            "description": "Tipo de campo. Acepta 'initial' o 'initials', 'textarea' o 'text_area'. Obligatorio para campos nuevos. Los campos url son de solo lectura automáticamente. Los campos file permiten a los firmantes subir archivos adjuntos (imágenes/PDF). Los campos stamp muestran una imagen preconfigurada."
                          },
                          "position": {
                            "type": "object",
                            "properties": {
                              "x": {
                                "type": "number",
                                "description": "Posición X en el documento"
                              },
                              "y": {
                                "type": "number",
                                "description": "Posición Y en el documento"
                              },
                              "width": {
                                "type": "number",
                                "description": "Ancho del campo"
                              },
                              "height": {
                                "type": "number",
                                "description": "Alto del campo"
                              }
                            },
                            "description": "Objeto de posición. Todas las propiedades son obligatorias para campos nuevos."
                          },
                          "page_number": {
                            "type": "integer",
                            "minimum": 1,
                            "description": "Número de página (indexado desde 1). Obligatorio para campos nuevos."
                          },
                          "required": {
                            "type": "boolean",
                            "description": "Si el campo es obligatorio"
                          },
                          "recipient_id": {
                            "type": "string",
                            "format": "uuid",
                            "nullable": true,
                            "description": "ID del destinatario al que se asigna el campo"
                          },
                          "variable_name": {
                            "type": "string",
                            "description": "Nombre de variable para el mapeo de datos prellenados"
                          },
                          "variable_defined_name": {
                            "type": "string",
                            "maxLength": 100,
                            "nullable": true,
                            "description": "Nombre legible de definición de campo personalizado. Se puede usar como alternativa a variable_name para apuntar a campos en la creación basada en plantilla."
                          },
                          "dropdown_options": {
                            "description": "Opciones para campos desplegables",
                            "oneOf": [
                              {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              },
                              {
                                "type": "object"
                              }
                            ]
                          },
                          "format_rules": {
                            "type": "object",
                            "description": "Reglas de formato (p. ej., formato de fecha, urlDisplayText para campos url, acceptedFileTypes para campos file)"
                          },
                          "validation_rules": {
                            "type": "object",
                            "description": "Reglas de validación para el campo"
                          },
                          "multi_group_id": {
                            "type": "string",
                            "format": "uuid",
                            "description": "ID de grupo para grupos de botones de opción"
                          },
                          "date_default": {
                            "type": "string",
                            "description": "Valor de fecha predeterminado"
                          },
                          "date_signing_default": {
                            "type": "boolean",
                            "description": "Para campos de fecha, usa la fecha de firma como valor predeterminado"
                          },
                          "read_only": {
                            "type": "boolean",
                            "description": "Si el campo es de solo lectura (automáticamente verdadero para campos url)"
                          },
                          "read_only_value": {
                            "type": "string",
                            "description": "Valor estático para campos de solo lectura. Para campos url, esta es la URL a la que enlazar."
                          },
                          "final_value": {
                            "type": "string",
                            "description": "Valor final del campo (para campos de solo lectura prellenados)"
                          }
                        }
                      }
                    }
                  }
                ]
              },
              "examples": {
                "update-properties": {
                  "summary": "Actualizar propiedades",
                  "value": {
                    "name": "Updated Contract Name",
                    "expiration_hours": 72
                  }
                },
                "update-recipient": {
                  "summary": "Actualizar destinatario único",
                  "value": {
                    "recipient": {
                      "id": "rec123-e89b-12d3-a456-426614174000",
                      "first_name": "John",
                      "last_name": "Smith",
                      "email": "john.smith@example.com",
                      "designation": "Signer",
                      "order": 1
                    }
                  }
                },
                "add-recipient": {
                  "summary": "Agregar nuevo destinatario",
                  "value": {
                    "recipient": {
                      "first_name": "Jane",
                      "last_name": "Doe",
                      "email": "jane@example.com",
                      "designation": "Signer",
                      "order": 2
                    }
                  }
                },
                "create-url-field": {
                  "summary": "Crear campo URL",
                  "value": {
                    "field": {
                      "type": "url",
                      "position": {
                        "x": 100,
                        "y": 200,
                        "width": 150,
                        "height": 30
                      },
                      "page_number": 1,
                      "read_only_value": "https://example.com/terms",
                      "format_rules": {
                        "urlDisplayText": "View Terms & Conditions"
                      }
                    }
                  }
                },
                "create-file-field": {
                  "summary": "Crear campo de subida de archivo",
                  "value": {
                    "field": {
                      "type": "file",
                      "position": {
                        "x": 100,
                        "y": 300,
                        "width": 200,
                        "height": 40
                      },
                      "page_number": 1,
                      "required": true,
                      "format_rules": {
                        "acceptedFileTypes": "image_and_pdf"
                      }
                    }
                  }
                },
                "update-field": {
                  "summary": "Actualizar posición de campo existente",
                  "value": {
                    "field": {
                      "id": "field123-e89b-12d3-a456-426614174000",
                      "position": {
                        "x": 120,
                        "y": 220
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Solicitud de firma actualizada correctamente. La forma de la respuesta depende de lo que se haya actualizado: la actualización de propiedades devuelve {id, name, template_description, document_url, expiration_hours}; la actualización de destinatario devuelve el objeto de destinatario completo; la actualización de campo devuelve el objeto de campo completo. La respuesta puede incluir un campo 'warning' para advertencias de validación de formato de correo electrónico (no bloqueante).",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 120 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "description": "Respuesta al actualizar propiedades",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "name": {
                          "type": "string"
                        },
                        "template_description": {
                          "type": "string",
                          "nullable": true
                        },
                        "document_url": {
                          "type": "string",
                          "format": "uri"
                        },
                        "expiration_hours": {
                          "type": "integer"
                        }
                      }
                    },
                    {
                      "type": "object",
                      "description": "Respuesta al actualizar/crear un destinatario"
                    },
                    {
                      "type": "object",
                      "description": "Respuesta al actualizar/crear un campo"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Solicitud Incorrecta - No se pueden actualizar propiedades y destinatario en la misma solicitud, o la solicitud de firma ya fue enviada/completada/cancelada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "cannot-update-sent": {
                    "value": {
                      "error": "Cannot update signing request",
                      "message": "Signing request has already been sent and cannot be modified"
                    }
                  },
                  "mixed-update": {
                    "value": {
                      "error": "Invalid request",
                      "message": "Cannot update both properties and recipient in the same request"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "patchSigningRequest",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signingRequests.patchSigningRequest({\n    id: \"id\",\n    body: {\n        name: \"Updated Contract Name\",\n        expiration_hours: 72\n    }\n});\nconsole.log(response);"
          }
        ]
      },
      "put": {
        "summary": "Actualización Integral de Solicitud de Firma",
        "description": "Realiza actualizaciones integrales a una solicitud de firma, incluyendo propiedades, destinatarios, campos y recordatorios. No se puede actualizar después de que la solicitud de firma haya sido enviada, completada o cancelada. Todas las secciones son opcionales, pero se debe proporcionar al menos una.\n\n**Patrón de ID Temporal para Nuevos Destinatarios**: Al agregar nuevos destinatarios en una actualización integral, usa el campo '_temp_id' (formato: 'temp_X') en lugar de 'id' para establecer relaciones con campos y recordatorios. Esto te permite crear nuevos destinatarios y referenciarlos en campos/recordatorios en una sola solicitud. Usa el campo 'id' para actualizar destinatarios existentes. Reglas de validación: (1) Los IDs temporales deben comenzar con 'temp_'; (2) Cada ID temporal debe ser único dentro de la solicitud; (3) Los campos y recordatorios pueden referenciar IDs temporales en su propiedad recipient_id; (4) La API resolverá automáticamente los IDs temporales a UUIDs reales después de la creación del destinatario.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID de la solicitud de firma"
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/UpdateSigningRequestBody"
        },
        "responses": {
          "200": {
            "description": "Solicitud de firma actualizada correctamente. Devuelve la solicitud de firma actualizada y un resumen de los cambios realizados.",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 120 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SigningRequestUpdateResponse"
                }
              }
            }
          },
          "400": {
            "description": "Errores de validación. Todos los errores de sección se devuelven juntos.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SigningRequestUpdateError"
                },
                "example": {
                  "error": "Validation failed",
                  "message": "Multiple validation errors occurred",
                  "details": {
                    "recipients": [
                      "Recipient 1: email is invalid"
                    ],
                    "deleted_recipients": [
                      "Cannot reassign: designations must match"
                    ],
                    "fields": [
                      "Field 2: x coordinate must be between 0 and 100"
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "updateSigningRequest",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signingRequests.updateSigningRequest({\n    id: \"id\",\n    signing_request_properties: {\n        name: \"Updated Contract Name\",\n        expiration_hours: 72\n    },\n    recipients: [{\n            id: \"rec1-e89b-12d3-a456-426614174000\",\n            first_name: \"John\",\n            last_name: \"Smith\",\n            email: \"john.smith@example.com\",\n            designation: \"Signer\",\n            order: 1\n        }, {\n            first_name: \"Jane\",\n            last_name: \"Doe\",\n            email: \"jane@example.com\",\n            designation: \"Signer\",\n            order: 2\n        }],\n    deleted_recipients: [{\n            recipient_id: \"rec2-e89b-12d3-a456-426614174000\",\n            field_action: \"reassign\",\n            reassign_to_recipient_id: \"rec1-e89b-12d3-a456-426614174000\"\n        }],\n    fields: [{\n            id: \"field1-e89b-12d3-a456-426614174000\",\n            type: \"signature\",\n            position: {\n                x: 15,\n                y: 85,\n                width: 30,\n                height: 10\n            },\n            page_number: 1,\n            required: true,\n            recipient_id: \"rec1-e89b-12d3-a456-426614174000\"\n        }],\n    reminders: [{\n            hours: 48,\n            all_users: true,\n            subject: \"Reminder: Please sign the document\",\n            message: \"This is a reminder to complete your signature.\"\n        }]\n});\nconsole.log(response);"
          }
        ]
      },
      "delete": {
        "summary": "Eliminar una solicitud de firma",
        "description": "Elimina una solicitud de firma no enviada (borrador). Solo se pueden eliminar las solicitudes de firma que no han sido enviadas. Para solicitudes de firma enviadas, usa el endpoint de cancelación en su lugar.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID de la solicitud de firma"
          }
        ],
        "responses": {
          "200": {
            "description": "Solicitud de firma eliminada correctamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 120 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SigningRequestDeleteResponse"
                },
                "example": {
                  "message": "Signing request deleted successfully",
                  "signing_request_id": "550e8400-e29b-41d4-a716-446655440000",
                  "deleted_on": "2026-05-30T10:00:00.000Z"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "409": {
            "description": "No se puede eliminar una solicitud de firma que ya ha sido enviada",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "Cannot delete a signing request that has been sent. Use cancel instead.",
                  "code": "ALREADY_SENT"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "deleteSigningRequest",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signingRequests.deleteSigningRequest({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/signing-requests/{id}/users": {
      "get": {
        "summary": "Obtener los usuarios de una solicitud de firma",
        "description": "Recupera todos los destinatarios/usuarios de una solicitud de firma específica",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID de la solicitud de firma",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Usuarios de la solicitud de firma recuperados correctamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 200 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solicitudes restantes en la ventana actual"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Marca de tiempo Unix en la que se reinicia el límite de tasa"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SigningRequestUserListResponse"
                },
                "example": {
                  "results": [
                    {
                      "id": "user123-e89b-12d3-a456-426614174000",
                      "name": "Alice Johnson",
                      "email": "alice@example.com",
                      "first_name": "Alice",
                      "last_name": "Johnson",
                      "designation": "Signer",
                      "order": 1,
                      "finished_on": "2024-03-15T14:30:00Z",
                      "declined_on": null,
                      "decline_reason": null,
                      "phone_number": "+1-555-0101",
                      "street_address": null,
                      "city": null,
                      "state_province": null,
                      "postal_code": null,
                      "country": null,
                      "title": "CEO",
                      "company": "Acme Corp",
                      "custom_fields": null,
                      "required_fields": [
                        "email",
                        "first_name"
                      ],
                      "missing_fields": [],
                      "required_read_only_fields": [],
                      "ready_to_send": true
                    },
                    {
                      "id": "user456-e89b-12d3-a456-426614174000",
                      "name": "Bob Williams",
                      "email": "bob@example.com",
                      "first_name": "Bob",
                      "last_name": "Williams",
                      "designation": "Signer",
                      "order": 2,
                      "finished_on": null,
                      "declined_on": null,
                      "decline_reason": null,
                      "phone_number": null,
                      "street_address": null,
                      "city": null,
                      "state_province": null,
                      "postal_code": null,
                      "country": null,
                      "title": null,
                      "company": null,
                      "custom_fields": null,
                      "required_fields": [
                        "email",
                        "first_name",
                        "phone_number"
                      ],
                      "missing_fields": [
                        "phone_number"
                      ],
                      "required_read_only_fields": [
                        {
                          "variable_name": "contract_amount",
                          "field_type": "number",
                          "has_value": false
                        }
                      ],
                      "ready_to_send": false
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "listSigningRequestUsers",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signingRequests.listSigningRequestUsers({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/signing-requests/{id}/fields": {
      "get": {
        "summary": "Obtener los campos de una solicitud de firma",
        "description": "Recupera todos los campos de una solicitud de firma específica con sus valores",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID de la solicitud de firma",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Campos de la solicitud de firma recuperados correctamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 200 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solicitudes restantes en la ventana actual"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Marca de tiempo Unix en la que se reinicia el límite de tasa"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SigningRequestFieldListResponse"
                },
                "example": {
                  "results": [
                    {
                      "id": "field789-e89b-12d3-a456-426614174000",
                      "type": "signature",
                      "recipient_id": "user456-e89b-12d3-a456-426614174000",
                      "required": true,
                      "read_only": false,
                      "value": "data:image/png;base64,iVBOR...",
                      "position": {
                        "x": 100.5,
                        "y": 200.75,
                        "width": 200,
                        "height": 50
                      },
                      "page_number": 1,
                      "variable_name": null,
                      "variable_defined_name": null,
                      "companies_workspaces_signing_requests_id": "sr123-e89b-12d3-a456-426614174000",
                      "companies_workspaces_signing_requests_users_id": "user456-e89b-12d3-a456-426614174000",
                      "field_type": "signature",
                      "x_postion": 100.5,
                      "y_position": 200.75,
                      "width": 200,
                      "heigh": 50,
                      "final_value": "data:image/png;base64,iVBOR...",
                      "deleted": 0
                    },
                    {
                      "id": "field012-e89b-12d3-a456-426614174000",
                      "type": "text",
                      "recipient_id": "user456-e89b-12d3-a456-426614174000",
                      "required": true,
                      "read_only": false,
                      "value": "Alice Johnson",
                      "position": {
                        "x": 150,
                        "y": 300,
                        "width": 250,
                        "height": 30
                      },
                      "page_number": 1,
                      "variable_name": "full_name",
                      "variable_defined_name": null,
                      "companies_workspaces_signing_requests_id": "sr123-e89b-12d3-a456-426614174000",
                      "companies_workspaces_signing_requests_users_id": "user456-e89b-12d3-a456-426614174000",
                      "field_type": "text",
                      "x_postion": 150,
                      "y_position": 300,
                      "width": 250,
                      "heigh": 30,
                      "final_value": "Alice Johnson",
                      "deleted": 0
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "listSigningRequestFields",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signingRequests.listSigningRequestFields({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/signing-requests/{id}/reminders": {
      "get": {
        "summary": "Obtener los recordatorios de una solicitud de firma",
        "description": "Recupera todos los recordatorios programados para una solicitud de firma específica",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID de la solicitud de firma",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Recordatorios de la solicitud de firma recuperados correctamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 200 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solicitudes restantes en la ventana actual"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Marca de tiempo Unix en la que se reinicia el límite de tasa"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Reminder"
                  }
                },
                "example": [
                  {
                    "id": "remind789-e89b-12d3-a456-426614174000",
                    "hours": 48,
                    "subject": "Urgent: Document signature required",
                    "message": "Please complete your signature at your earliest convenience.",
                    "all_users": false,
                    "template_user_id": "user456-e89b-12d3-a456-426614174000",
                    "date_created": "2024-03-10T09:00:00Z",
                    "date_changed": "2024-03-10T09:00:00Z"
                  }
                ]
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "listSigningRequestReminders",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signingRequests.listSigningRequestReminders({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/signing-requests/{id}/audit": {
      "get": {
        "summary": "Obtener el registro de auditoría de una solicitud de firma",
        "description": "Recupera el registro de auditoría completo de una solicitud de firma, combinando acciones de administrador (creada, editada, enviada, cancelada) y acciones del firmante (vista, firmada, rechazada, descargada). Los eventos se ordenan cronológicamente.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID de la solicitud de firma"
          }
        ],
        "responses": {
          "200": {
            "description": "Registro de auditoría recuperado correctamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 120 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuditTrailListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "listSigningRequestAuditTrail",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signingRequests.listSigningRequestAuditTrail({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/signing-requests/{id}/send": {
      "post": {
        "summary": "Enviar solicitud de firma",
        "description": "Envía una solicitud de firma a todos los destinatarios por correo electrónico. Esto activa el envío del correo y establece la marca de tiempo sent_on.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID de la solicitud de firma",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Solicitud de firma enviada correctamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 60 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solicitudes restantes en la ventana actual"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Marca de tiempo Unix en la que se reinicia el límite de tasa"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SendSigningRequestResponse"
                },
                "example": {
                  "message": "Signing request sent successfully",
                  "signing_request_id": "123e4567-e89b-12d3-a456-426614174000",
                  "recipients_notified": 3,
                  "sent_date": "2024-03-20T10:15:00Z",
                  "expires_at": "2024-04-20T10:15:00Z"
                }
              }
            }
          },
          "400": {
            "description": "Solicitud incorrecta - La solicitud de firma ya fue enviada o ha expirado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "alreadySent": {
                    "value": {
                      "error": "Bad Request",
                      "message": "Signing request has already been sent"
                    }
                  },
                  "expired": {
                    "value": {
                      "error": "Bad Request",
                      "message": "Signing request has expired"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "sendSigningRequest",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signingRequests.sendSigningRequest({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/signing-requests/{id}/cancel": {
      "post": {
        "summary": "Cancelar una solicitud de firma",
        "description": "Cancela una solicitud de firma que aún no se ha completado. Solo se pueden cancelar solicitudes que ya fueron enviadas y que no estén ya finalizadas o canceladas.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID de la solicitud de firma"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "type": "string",
                    "maxLength": 500,
                    "description": "Motivo de cancelación opcional"
                  },
                  "notify_signers": {
                    "type": "boolean",
                    "default": true,
                    "description": "Indica si se debe notificar a los firmantes de la cancelación"
                  }
                }
              },
              "example": {
                "reason": "No longer needed",
                "notify_signers": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Solicitud de firma cancelada correctamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 120 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CancelSigningRequestResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "409": {
            "description": "No se puede cancelar (ya cancelada, finalizada, o no enviada)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "cancelSigningRequest",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signingRequests.cancelSigningRequest({\n    id: \"id\",\n    reason: \"No longer needed\",\n    notify_signers: true\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/signing-requests/{id}/resend": {
      "post": {
        "summary": "Reenviar solicitud de firma a destinatarios específicos",
        "description": "Reenvía las notificaciones de la solicitud de firma a uno o más destinatarios que actualmente son elegibles para firmar. Para solicitudes con orden de firma habilitado, solo se puede reenviar a los destinatarios en el orden activo actual. No se puede reenviar a destinatarios que ya han firmado.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID de la solicitud de firma"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "recipient_ids"
                ],
                "properties": {
                  "recipient_ids": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "description": "Array de IDs de usuario de los destinatarios a los que se les reenviará",
                    "minItems": 1
                  },
                  "custom_message": {
                    "type": "string",
                    "maxLength": 1000,
                    "description": "Mensaje personalizado opcional para incluir en la notificación de reenvío"
                  }
                }
              },
              "example": {
                "recipient_ids": [
                  "123e4567-e89b-12d3-a456-426614174000"
                ],
                "custom_message": "Gentle reminder to complete your signature"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Solicitud de firma reenviada correctamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 120 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResendSigningRequestResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "409": {
            "description": "No se puede reenviar (los destinatarios ya firmaron, el orden de firma no es válido, o la solicitud no está enviada/cancelada/finalizada)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResendConflictError"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "resendSigningRequest",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signingRequests.resendSigningRequest({\n    id: \"id\",\n    recipient_ids: [\"123e4567-e89b-12d3-a456-426614174000\"],\n    custom_message: \"Gentle reminder to complete your signature\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/webhooks": {
      "get": {
        "summary": "Listar Webhooks",
        "description": "Recupera una lista paginada de webhooks",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            },
            "description": "Número de página"
          },
          {
            "name": "page_size",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "description": "Elementos por página"
          },
          {
            "name": "enabled",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "0",
                "1"
              ]
            },
            "description": "Filtrar por estado habilitado (0=deshabilitado, 1=habilitado)"
          },
          {
            "name": "url",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filtrar por URL del webhook (coincidencia parcial, sin distinguir mayúsculas/minúsculas)"
          },
          {
            "name": "event",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filtrar por tipo de evento (por ejemplo, 'signing_request.completed')"
          },
          {
            "name": "created_after",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Filtrar webhooks creados después de esta fecha (formato ISO 8601)"
          },
          {
            "name": "created_before",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Filtrar webhooks creados antes de esta fecha (formato ISO 8601)"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "url",
                "enabled",
                "created_on",
                "last_changed_on",
                "consecutive_failures"
              ],
              "default": "created_on"
            },
            "description": "Campo por el cual ordenar"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Orden de clasificación"
          },
          {
            "name": "workspace_id",
            "in": "query",
            "description": "Filtrar webhooks por espacio de trabajo. Cuando se proporciona, devuelve solo los webhooks asociados a ese espacio de trabajo. Cuando se omite, devuelve solo los webhooks a nivel de empresa.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Webhooks recuperados correctamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 200 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookListResponse"
                }
              }
            }
          },
          "400": {
            "description": "Error de validación - formato de fecha o parámetros de ordenación no válidos",
            "content": {
              "application/json": {
                "examples": {
                  "invalidDate": {
                    "summary": "Formato de fecha no válido",
                    "value": {
                      "error": "Validation failed",
                      "code": "VALIDATION_ERROR",
                      "details": [
                        {
                          "path": [
                            "created_before"
                          ],
                          "message": "created_before must be a valid ISO 8601 date"
                        }
                      ]
                    }
                  },
                  "invalidSort": {
                    "summary": "Parámetro de ordenación no válido",
                    "value": {
                      "error": "Validation failed",
                      "code": "VALIDATION_ERROR",
                      "details": [
                        {
                          "path": [
                            "sort_by"
                          ],
                          "message": "Invalid sort field"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "listWebhooks",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.webhooks.listWebhooks();\nconsole.log(response);"
          }
        ]
      },
      "post": {
        "summary": "Crear Webhook",
        "description": "Crear un nuevo webhook",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "url",
                  "events"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "events": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "workspace_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "ID de espacio de trabajo opcional. Cuando se proporciona, crea un webhook a nivel de espacio de trabajo. Cuando se omite, crea un webhook a nivel de empresa."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Webhook creado exitosamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 60 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Webhook"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "createWebhook",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.webhooks.createWebhook({\n    url: \"url\",\n    events: [\"events\"]\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/webhooks/{id}": {
      "get": {
        "summary": "Obtener Webhook",
        "description": "Recuperar un webhook específico por ID",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Webhook recuperado exitosamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 200 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Webhook"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "getWebhook",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.webhooks.getWebhook({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      },
      "put": {
        "summary": "Actualizar Webhook",
        "description": "Actualizar un webhook existente",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "events": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Webhook actualizado exitosamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 60 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Webhook"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "updateWebhook",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.webhooks.updateWebhook({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      },
      "delete": {
        "summary": "Eliminar un webhook",
        "description": "Eliminar de forma lógica un webhook por ID. Esto marca el webhook como eliminado pero conserva los datos.",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID del webhook",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Webhook eliminado exitosamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 60 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solicitudes restantes en la ventana actual"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Marca de tiempo Unix en la que se reinicia el límite de tasa"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageResponse"
                },
                "example": {
                  "message": "Webhook deleted successfully"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "deleteWebhook",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.webhooks.deleteWebhook({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/webhooks/{id}/test": {
      "post": {
        "summary": "Probar un webhook",
        "description": "Enviar una carga de prueba a la URL del webhook para verificar que funciona correctamente",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID del webhook",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Webhook de prueba enviado exitosamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 10 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solicitudes restantes en la ventana actual"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Marca de tiempo Unix en la que se reinicia el límite de tasa"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TestWebhookResponse"
                },
                "example": {
                  "success": true,
                  "status_code": 200,
                  "webhook_event_id": "123e4567-e89b-12d3-a456-426614174000",
                  "message": "Test webhook delivered successfully",
                  "headers_sent": {
                    "X-Firma-Event": "webhook.test",
                    "X-Firma-Signature": "Generated HMAC-SHA256 signature",
                    "X-Firma-Delivery": "123e4567-e89b-12d3-a456-426614174000"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "testWebhook",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.webhooks.testWebhook({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/webhooks/rotate-secret": {
      "post": {
        "summary": "Rotar secret de firma del webhook",
        "description": "Genera un nuevo secret de firma de webhook para la empresa. El secret anterior sigue siendo válido durante 7 días para permitir una migración sin problemas. Limitado a 1 solicitud por minuto.",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Secret rotado exitosamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 1 solicitud por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RotateSecretResponse"
                },
                "example": {
                  "message": "Webhook secret rotated successfully",
                  "new_secret": "a1b2c3d4e5f6...",
                  "grace_period_hours": 168,
                  "warning": "Update your webhook signature verification to use the new secret. The old secret will remain valid for 7 days."
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "description": "Límite de tasa excedido (1 rotación por minuto)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "rotateWebhookSecret",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.webhooks.rotateWebhookSecret();\nconsole.log(response);"
          }
        ]
      }
    },
    "/webhooks/secret-status": {
      "get": {
        "summary": "Obtener estado de rotación del secret del webhook",
        "description": "Devuelve información sobre el secret de webhook actual, incluyendo el estado de rotación y la expiración del secret anterior, si corresponde.",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Estado del secret recuperado exitosamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 200 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SecretStatusResponse"
                },
                "example": {
                  "created_at": "2025-09-01T10:00:00Z",
                  "last_rotated_at": "2025-10-16T12:00:00Z",
                  "grace_period_active": true,
                  "grace_period_ends_at": "2025-10-23T12:00:00Z"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "description": "No se encontró configuración de webhook",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "getWebhookSecretStatus",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.webhooks.getWebhookSecretStatus();\nconsole.log(response);"
          }
        ]
      }
    },
    "/generate-template-token": {
      "post": {
        "summary": "Generar token JWT para incrustar plantillas",
        "description": "Crea un token JWT para incrustar una plantilla con una expiración de 24 horas. Este es el endpoint estándar para la generación de JWT.\n\n**Nota**: La función independiente `generate-embedded-template-token` está en desuso a favor de este endpoint basado en router.",
        "tags": [
          "JWT Management"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GenerateJWTRequest"
              },
              "example": {
                "companies_workspaces_templates_id": "123e4567-e89b-12d3-a456-426614174000"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "JWT generado exitosamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 120 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solicitudes restantes en la ventana actual"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Marca de tiempo Unix en la que se reinicia el límite de tasa"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GenerateTemplateTokenResponse"
                },
                "example": {
                  "token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
                  "expires_at": "2024-04-20T10:00:00Z",
                  "jwt_record_id": "jwt123-e89b-12d3-a456-426614174000"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "generateTemplateToken",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.jwtManagement.generateTemplateToken({\n    companies_workspaces_templates_id: \"123e4567-e89b-12d3-a456-426614174000\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/revoke-template-token": {
      "post": {
        "summary": "Revocar Token JWT de Plantilla",
        "description": "Revoca un token JWT generado previamente, impidiendo que se use para incrustar plantillas. Este es el endpoint estándar para revocar JWT de plantillas.",
        "tags": [
          "JWT Management"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RevokeJWTRequest"
              },
              "example": {
                "jwt_id": "123e4567-e89b-12d3-a456-426614174000"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "JWT revocado exitosamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 120 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solicitudes restantes en la ventana actual"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Marca de tiempo Unix en la que se reinicia el límite de tasa"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RevokeJWTResponse"
                },
                "example": {
                  "message": "JWT revoked successfully",
                  "jwt_id": "123e4567-e89b-12d3-a456-426614174000",
                  "revoked_at": "2024-03-20T16:45:00Z"
                }
              }
            }
          },
          "400": {
            "description": "Solicitud Incorrecta - JWT ya revocado o inválido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "alreadyRevoked": {
                    "value": {
                      "error": "Bad Request",
                      "message": "JWT has already been revoked"
                    }
                  },
                  "invalidJwt": {
                    "value": {
                      "error": "Bad Request",
                      "message": "Invalid JWT ID"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "revokeTemplateToken",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.jwtManagement.revokeTemplateToken({\n    jwt_id: \"123e4567-e89b-12d3-a456-426614174000\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/jwt/generate-signing-request": {
      "post": {
        "summary": "Generar token JWT para solicitud de firma",
        "description": "Generar un token JWT para incrustar un editor de solicitud de firma. El JWT expira después de 7 días.",
        "tags": [
          "JWT Management"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GenerateSigningRequestJWTRequest"
              },
              "example": {
                "companies_workspaces_signing_requests_id": "123e4567-e89b-12d3-a456-426614174000"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "JWT generado exitosamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 120 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solicitudes restantes en la ventana actual"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Marca de tiempo Unix en la que se reinicia el límite de tasa"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GenerateSigningRequestJWTResponse"
                },
                "example": {
                  "jwt": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
                  "jwt_id": "jwt123-e89b-12d3-a456-426614174000",
                  "expires_at": "2024-03-27T10:00:00Z",
                  "signing_request_id": "123e4567-e89b-12d3-a456-426614174000"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "generateSigningRequestToken",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.jwtManagement.generateSigningRequestToken({\n    companies_workspaces_signing_requests_id: \"123e4567-e89b-12d3-a456-426614174000\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/jwt/revoke-signing-request": {
      "post": {
        "summary": "Revocar un token JWT de solicitud de firma",
        "description": "Revocar un token JWT generado previamente para una solicitud de firma, impidiendo que se use para edición incrustada",
        "tags": [
          "JWT Management"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RevokeSigningRequestJWTRequest"
              },
              "example": {
                "jwt_id": "123e4567-e89b-12d3-a456-426614174000"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "JWT revocado exitosamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 120 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Solicitudes restantes en la ventana actual"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Marca de tiempo Unix en la que se reinicia el límite de tasa"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RevokeSigningRequestJWTResponse"
                },
                "example": {
                  "message": "JWT revoked successfully",
                  "jwt_id": "123e4567-e89b-12d3-a456-426614174000",
                  "revoked_at": "2024-03-20T16:45:00Z"
                }
              }
            }
          },
          "400": {
            "description": "Solicitud Incorrecta - JWT ya revocado o inválido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "alreadyRevoked": {
                    "value": {
                      "error": "Bad Request",
                      "message": "JWT has already been revoked"
                    }
                  },
                  "invalidJwt": {
                    "value": {
                      "error": "Bad Request",
                      "message": "Invalid JWT ID"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "revokeSigningRequestToken",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.jwtManagement.revokeSigningRequestToken({\n    jwt_id: \"123e4567-e89b-12d3-a456-426614174000\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/workspace/{workspace_id}/email-templates": {
      "get": {
        "summary": "Listar plantillas de correo del espacio de trabajo",
        "description": "Recuperar todas las plantillas de correo personalizadas de un espacio de trabajo",
        "tags": [
          "Email Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID del espacio de trabajo"
          }
        ],
        "responses": {
          "200": {
            "description": "Plantillas de correo recuperadas exitosamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkspaceEmailTemplateListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "listWorkspaceEmailTemplates",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailTemplates.listWorkspaceEmailTemplates({\n    workspace_id: \"workspace_id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/workspace/{workspace_id}/email-templates/{email_type}": {
      "get": {
        "summary": "Obtener plantilla de correo del espacio de trabajo",
        "description": "Recuperar una plantilla de correo específica por tipo para un espacio de trabajo",
        "tags": [
          "Email Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID del espacio de trabajo"
          },
          {
            "name": "email_type",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "signing_invite",
                "next_signer",
                "signing_expired",
                "signing_cancelled",
                "signing_declined"
              ]
            },
            "description": "Tipo de plantilla de correo"
          }
        ],
        "responses": {
          "200": {
            "description": "Plantilla de correo recuperada exitosamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailTemplate"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "getWorkspaceEmailTemplate",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailTemplates.getWorkspaceEmailTemplate({\n    workspace_id: \"workspace_id\",\n    email_type: \"signing_invite\"\n});\nconsole.log(response);"
          }
        ]
      },
      "put": {
        "summary": "Crear o actualizar plantilla de correo del espacio de trabajo",
        "description": "Crear o actualizar una plantilla de correo personalizada para un tipo específico. Si ya existe una plantilla para este tipo, se actualizará. Se devuelve una advertencia si el cuerpo de la plantilla no contiene {{signing_link}}.",
        "tags": [
          "Email Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID del espacio de trabajo"
          },
          {
            "name": "email_type",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "signing_invite",
                "next_signer",
                "signing_expired",
                "signing_cancelled",
                "signing_declined"
              ]
            },
            "description": "Tipo de plantilla de correo"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "subject",
                  "body"
                ],
                "properties": {
                  "subject": {
                    "type": "string",
                    "maxLength": 500,
                    "description": "Línea de asunto del correo"
                  },
                  "body": {
                    "type": "string",
                    "maxLength": 50000,
                    "description": "Cuerpo del correo (HTML). Use el marcador de posición {{signing_link}} para la URL de firma."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Plantilla de correo actualizada exitosamente",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/EmailTemplate"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "warnings": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "201": {
            "description": "Plantilla de correo creada exitosamente",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/EmailTemplate"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "warnings": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "updateWorkspaceEmailTemplate",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailTemplates.updateWorkspaceEmailTemplate({\n    workspace_id: \"workspace_id\",\n    email_type: \"signing_invite\",\n    subject: \"subject\",\n    body: \"body\"\n});\nconsole.log(response);"
          }
        ]
      },
      "delete": {
        "summary": "Eliminar plantilla de correo del espacio de trabajo",
        "description": "Elimina una plantilla de correo personalizada. El espacio de trabajo volverá a usar la plantilla a nivel de empresa o la plantilla predeterminada para este tipo.",
        "tags": [
          "Email Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID del espacio de trabajo"
          },
          {
            "name": "email_type",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "signing_invite",
                "next_signer",
                "signing_expired",
                "signing_cancelled",
                "signing_declined"
              ]
            },
            "description": "Tipo de plantilla de correo"
          }
        ],
        "responses": {
          "200": {
            "description": "Plantilla de correo eliminada exitosamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailTemplateDeleteResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "deleteWorkspaceEmailTemplate",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailTemplates.deleteWorkspaceEmailTemplate({\n    workspace_id: \"workspace_id\",\n    email_type: \"signing_invite\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/company/email-templates": {
      "get": {
        "summary": "Listar plantillas de correo de la empresa",
        "description": "Obtiene todas las plantillas de correo personalizadas a nivel de empresa. Las plantillas de empresa sirven como valores predeterminados para todos los espacios de trabajo que no tienen plantillas propias.",
        "tags": [
          "Email Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Plantillas de correo de la empresa obtenidas exitosamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompanyEmailTemplateListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "listCompanyEmailTemplates",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailTemplates.listCompanyEmailTemplates();\nconsole.log(response);"
          }
        ]
      }
    },
    "/company/email-templates/{email_type}": {
      "put": {
        "summary": "Crear o actualizar plantilla de correo de la empresa",
        "description": "Crea o actualiza una plantilla de correo a nivel de empresa para un tipo específico. Las plantillas de empresa se usan como valores predeterminados para los espacios de trabajo que no tienen plantillas propias.",
        "tags": [
          "Email Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "email_type",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "signing_invite",
                "next_signer",
                "signing_expired",
                "signing_cancelled",
                "signing_declined"
              ]
            },
            "description": "Tipo de plantilla de correo"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "subject",
                  "body"
                ],
                "properties": {
                  "subject": {
                    "type": "string",
                    "maxLength": 500,
                    "description": "Línea de asunto del correo"
                  },
                  "body": {
                    "type": "string",
                    "maxLength": 50000,
                    "description": "Cuerpo del correo (HTML). Usa el marcador {{signing_link}} para la URL de firma."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Plantilla de correo de la empresa actualizada exitosamente",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/EmailTemplate"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "warnings": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "201": {
            "description": "Plantilla de correo de la empresa creada exitosamente",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/EmailTemplate"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "warnings": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "updateCompanyEmailTemplate",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailTemplates.updateCompanyEmailTemplate({\n    email_type: \"signing_invite\",\n    subject: \"subject\",\n    body: \"body\"\n});\nconsole.log(response);"
          }
        ]
      },
      "delete": {
        "summary": "Eliminar plantilla de correo de la empresa",
        "description": "Elimina una plantilla de correo a nivel de empresa. Los espacios de trabajo volverán a usar la plantilla predeterminada incorporada para este tipo.",
        "tags": [
          "Email Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "email_type",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "signing_invite",
                "next_signer",
                "signing_expired",
                "signing_cancelled",
                "signing_declined"
              ]
            },
            "description": "Tipo de plantilla de correo"
          }
        ],
        "responses": {
          "200": {
            "description": "Plantilla de correo de la empresa eliminada exitosamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailTemplateDeleteResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "deleteCompanyEmailTemplate",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailTemplates.deleteCompanyEmailTemplate({\n    email_type: \"signing_invite\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/company/signer-terms": {
      "get": {
        "summary": "Listar términos del firmante de la empresa",
        "description": "Obtiene todos los términos del firmante a nivel de empresa. Los términos del firmante de la empresa sirven como valores predeterminados para los espacios de trabajo que no tienen términos propios.",
        "tags": [
          "Signer Terms"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Términos del firmante de la empresa obtenidos exitosamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SignerTermsListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "listCompanySignerTerms",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signerTerms.listCompanySignerTerms();\nconsole.log(response);"
          }
        ]
      }
    },
    "/company/signer-terms/{language}": {
      "put": {
        "summary": "Crear o actualizar términos del firmante de la empresa",
        "description": "Crea o actualiza los términos del firmante a nivel de empresa para un idioma específico. El texto enviado se sanitiza antes de guardarse.",
        "tags": [
          "Signer Terms"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "language",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "es",
                "it",
                "pt",
                "fr",
                "de",
                "el",
                "ru",
                "pl"
              ]
            },
            "description": "Código de idioma"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "statement_text"
                ],
                "properties": {
                  "statement_text": {
                    "type": "string",
                    "description": "Texto de consentimiento del firmante en HTML. Se sanitiza antes de guardarse."
                  },
                  "terms_url": {
                    "type": "string",
                    "format": "uri",
                    "nullable": true,
                    "description": "Enlace externo opcional a los términos"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Términos del firmante de la empresa actualizados exitosamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SignerTermsUpdateResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "updateCompanySignerTerms",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signerTerms.updateCompanySignerTerms({\n    language: \"en\",\n    statement_text: \"statement_text\"\n});\nconsole.log(response);"
          }
        ]
      },
      "delete": {
        "summary": "Eliminar términos del firmante de la empresa",
        "description": "Elimina los términos del firmante a nivel de empresa para un idioma específico.",
        "tags": [
          "Signer Terms"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "language",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "es",
                "it",
                "pt",
                "fr",
                "de",
                "el",
                "ru",
                "pl"
              ]
            },
            "description": "Código de idioma"
          }
        ],
        "responses": {
          "200": {
            "description": "Términos del firmante de la empresa eliminados exitosamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SignerTermsDeleteResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "deleteCompanySignerTerms",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signerTerms.deleteCompanySignerTerms({\n    language: \"en\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/workspace/{workspace_id}/signer-terms": {
      "get": {
        "summary": "Listar términos del firmante del espacio de trabajo",
        "description": "Obtiene todos los términos del firmante personalizados de un espacio de trabajo",
        "tags": [
          "Signer Terms"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID del espacio de trabajo"
          }
        ],
        "responses": {
          "200": {
            "description": "Términos del firmante del espacio de trabajo obtenidos exitosamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SignerTermsListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "listWorkspaceSignerTerms",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signerTerms.listWorkspaceSignerTerms({\n    workspace_id: \"workspace_id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/workspace/{workspace_id}/signer-terms/{language}": {
      "put": {
        "summary": "Crear o actualizar términos del firmante del espacio de trabajo",
        "description": "Crea o actualiza los términos del firmante a nivel de espacio de trabajo para un idioma específico. El texto enviado se sanitiza antes de guardarse.",
        "tags": [
          "Signer Terms"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID del espacio de trabajo"
          },
          {
            "name": "language",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "es",
                "it",
                "pt",
                "fr",
                "de",
                "el",
                "ru",
                "pl"
              ]
            },
            "description": "Código de idioma"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "statement_text"
                ],
                "properties": {
                  "statement_text": {
                    "type": "string",
                    "description": "Texto de consentimiento del firmante en HTML. Se sanitiza antes de guardarse."
                  },
                  "terms_url": {
                    "type": "string",
                    "format": "uri",
                    "nullable": true,
                    "description": "Enlace externo opcional a los términos"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Términos del firmante del espacio de trabajo actualizados exitosamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SignerTermsUpdateResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "updateWorkspaceSignerTerms",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signerTerms.updateWorkspaceSignerTerms({\n    workspace_id: \"workspace_id\",\n    language: \"en\",\n    statement_text: \"statement_text\"\n});\nconsole.log(response);"
          }
        ]
      },
      "delete": {
        "summary": "Eliminar términos del firmante del espacio de trabajo",
        "description": "Elimina los términos del firmante a nivel de espacio de trabajo para un idioma específico.",
        "tags": [
          "Signer Terms"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID del espacio de trabajo"
          },
          {
            "name": "language",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "es",
                "it",
                "pt",
                "fr",
                "de",
                "el",
                "ru",
                "pl"
              ]
            },
            "description": "Código de idioma"
          }
        ],
        "responses": {
          "200": {
            "description": "Términos del firmante del espacio de trabajo eliminados exitosamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SignerTermsDeleteResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "deleteWorkspaceSignerTerms",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signerTerms.deleteWorkspaceSignerTerms({\n    workspace_id: \"workspace_id\",\n    language: \"en\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/email-templates/defaults/{language}": {
      "get": {
        "summary": "Obtener plantillas de correo predeterminadas",
        "description": "Obtiene las plantillas de correo predeterminadas incorporadas para un idioma específico. Son las plantillas que se usan cuando no hay plantillas de empresa o de espacio de trabajo personalizadas configuradas.",
        "tags": [
          "Email Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "language",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "es",
                "it",
                "pt",
                "fr",
                "de",
                "el",
                "ru",
                "pl"
              ]
            },
            "description": "Código de idioma"
          }
        ],
        "responses": {
          "200": {
            "description": "Plantillas predeterminadas obtenidas exitosamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailTemplateDefaultsResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "getEmailTemplateDefaults",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailTemplates.getEmailTemplateDefaults({\n    language: \"en\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/email-templates/placeholders": {
      "get": {
        "summary": "Obtener marcadores de plantillas de correo",
        "description": "Obtiene la lista de marcadores disponibles que se pueden usar en las plantillas de correo. Los marcadores se reemplazan con valores reales cuando se envían los correos.",
        "tags": [
          "Email Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Marcadores obtenidos exitosamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailTemplatePlaceholdersResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "listEmailTemplatePlaceholders",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailTemplates.listEmailTemplatePlaceholders();\nconsole.log(response);"
          }
        ]
      }
    },
    "/workspace/{workspace_id}/settings": {
      "get": {
        "summary": "Obtener configuración del espacio de trabajo",
        "description": "Obtiene la configuración del espacio de trabajo",
        "tags": [
          "Workspace Settings"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Configuración del espacio de trabajo obtenida exitosamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 200 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkspaceSettings"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "getWorkspaceSettings",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.workspaceSettings.getWorkspaceSettings({\n    workspace_id: \"workspace_id\"\n});\nconsole.log(response);"
          }
        ]
      },
      "put": {
        "summary": "Actualizar configuración del espacio de trabajo",
        "description": "Actualiza la configuración del espacio de trabajo",
        "tags": [
          "Workspace Settings"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "signing_request_email_header": {
                    "type": "string"
                  },
                  "signing_request_email_body": {
                    "type": "string"
                  },
                  "team_email": {
                    "type": "string",
                    "format": "email"
                  },
                  "timezone": {
                    "type": "string"
                  },
                  "language": {
                    "type": "string",
                    "enum": [
                      "en",
                      "es",
                      "it",
                      "pt",
                      "fr",
                      "de",
                      "el",
                      "ru",
                      "pl"
                    ],
                    "description": "Idioma del espacio de trabajo para las plantillas de correo"
                  },
                  "show_credit_cost_in_editor": {
                    "type": "boolean",
                    "description": "Si se debe mostrar el costo en créditos en los editores incrustados"
                  },
                  "require_otp_verification": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "Si los firmantes deben verificar su correo mediante OTP. null = heredar de la empresa"
                  },
                  "require_terms_acceptance": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "Si los firmantes deben aceptar los términos antes de firmar. null hereda la configuración a nivel de empresa."
                  },
                  "disable_guided_navigation": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "Desactiva el desplazamiento automático al siguiente campo requerido durante la firma. Hereda del espacio de trabajo o de la empresa si no se establece."
                  },
                  "show_signature_frame": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "Si se deben renderizar los marcos de firma en los PDF completados. null = heredar de la empresa"
                  },
                  "color_primary": {
                    "type": "string",
                    "nullable": true,
                    "description": "Color primario personalizado (hex #rrggbb). Null para heredar de la empresa."
                  },
                  "color_primary_fg": {
                    "type": "string",
                    "nullable": true,
                    "description": "Anulación del color de primer plano primario. Null para heredar de la empresa."
                  },
                  "color_background": {
                    "type": "string",
                    "nullable": true,
                    "description": "Anulación del color de fondo. Null para heredar de la empresa."
                  },
                  "color_foreground": {
                    "type": "string",
                    "nullable": true,
                    "description": "Anulación del color de primer plano/texto. Null para heredar de la empresa."
                  },
                  "color_card": {
                    "type": "string",
                    "nullable": true,
                    "description": "Anulación del color de fondo de la tarjeta. Null para heredar de la empresa."
                  },
                  "color_border": {
                    "type": "string",
                    "nullable": true,
                    "description": "Anulación del color del borde. Null para heredar de la empresa."
                  },
                  "color_accent": {
                    "type": "string",
                    "nullable": true,
                    "description": "Color de acento de la interfaz del editor. Null para heredar de la empresa."
                  },
                  "color_accent_fg": {
                    "type": "string",
                    "nullable": true,
                    "description": "Color de primer plano en superficies de acento. Null para heredar de la empresa."
                  },
                  "color_canvas": {
                    "type": "string",
                    "nullable": true,
                    "description": "Color del entorno del lienzo del documento en el editor. Null para heredar de la empresa."
                  },
                  "color_muted": {
                    "type": "string",
                    "nullable": true,
                    "description": "Color de superficie atenuado. Null para heredar de la empresa."
                  },
                  "color_muted_fg": {
                    "type": "string",
                    "nullable": true,
                    "description": "Color de texto atenuado. Null para heredar de la empresa."
                  },
                  "email_local_part": {
                    "type": "string",
                    "nullable": true,
                    "description": "La parte local (antes del @) de la dirección de correo del remitente. Null para heredar de la configuración de la empresa.",
                    "pattern": "^[a-z0-9]([a-z0-9._-]*[a-z0-9])?$",
                    "minLength": 1,
                    "maxLength": 64
                  },
                  "allow_presigning_download": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "Permite a los firmantes descargar el documento original antes de firmar. Hereda de la configuración del espacio de trabajo o de la empresa cuando es null."
                  },
                  "show_partial_watermark": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "Muestra una marca de agua de EN PROGRESO en las descargas parciales de PDF cuando no todos los firmantes han completado. null hereda la configuración a nivel de empresa."
                  },
                  "show_qr_code": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "Muestra un código QR en la página de firma que permite a los firmantes continuar desde su teléfono. Hereda de la configuración del espacio de trabajo o de la empresa cuando es null."
                  },
                  "signing_button_label_overrides": {
                    "type": "object",
                    "nullable": true,
                    "description": "Etiquetas de botón personalizadas por idioma para la vista de firma. Las claves son códigos de idioma (en, de, etc.); los valores son objetos que mapean claves de traducción a texto personalizado. Null para usar los valores predeterminados.",
                    "additionalProperties": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Configuración del espacio de trabajo actualizada correctamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 120 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkspaceSettings"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "updateWorkspaceSettings",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.workspaceSettings.updateWorkspaceSettings({\n    workspace_id: \"workspace_id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/workspace/{workspace_id}/domains": {
      "get": {
        "summary": "Listar dominios del espacio de trabajo",
        "description": "Lista todos los dominios de correo electrónico configurados para un espacio de trabajo específico. Estos dominios se usan para enviar correos de solicitudes de firma desde este espacio de trabajo.",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID del espacio de trabajo"
          }
        ],
        "responses": {
          "200": {
            "description": "Dominios del espacio de trabajo obtenidos correctamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 200 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DomainListResponse"
                },
                "example": {
                  "results": [
                    {
                      "id": "123e4567-e89b-12d3-a456-426614174000",
                      "domain": "sales.acme.com",
                      "verification_status": 2,
                      "domain_status": 1,
                      "is_primary": true,
                      "date_created": "2024-01-15T10:30:00Z",
                      "date_changed": "2024-01-16T14:00:00Z"
                    }
                  ],
                  "workspace_id": "456e4567-e89b-12d3-a456-426614174000"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "listWorkspaceDomains",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailDomains.listWorkspaceDomains({\n    workspace_id: \"workspace_id\"\n});\nconsole.log(response);"
          }
        ]
      },
      "post": {
        "summary": "Agregar dominio del espacio de trabajo",
        "description": "Agrega un nuevo dominio de correo electrónico para un espacio de trabajo específico. Esto inicia el proceso de verificación del dominio. Después de la creación, debes:\n1. Agregar un registro TXT a tu DNS con el token de verificación\n2. Llamar a POST /workspace/{workspace_id}/domains/{id}/verify-ownership para verificar la propiedad del dominio\n3. Llamar a POST /workspace/{workspace_id}/domains/{id}/finalize para registrar con el proveedor de correo electrónico\n4. Agregar los registros DNS devueltos (SPF, DKIM, etc.)\n5. Llamar a POST /workspace/{workspace_id}/domains/{id}/verify-dns para completar la verificación",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID del espacio de trabajo"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "domain"
                ],
                "properties": {
                  "domain": {
                    "type": "string",
                    "description": "Nombre de dominio a agregar (por ejemplo, 'example.com'). Debe tener un formato de dominio válido.",
                    "example": "sales.acme.com"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Dominio creado correctamente. Agrega el registro TXT de verificación a tu DNS.",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 120 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DomainCreateResponse"
                },
                "example": {
                  "domain": {
                    "id": "123e4567-e89b-12d3-a456-426614174000",
                    "domain": "sales.acme.com",
                    "verification_status": 0,
                    "domain_status": 0,
                    "is_primary": false,
                    "verification_token": "firma-verify=abc123xyz",
                    "date_created": "2024-01-15T10:30:00Z",
                    "date_changed": "2024-01-15T10:30:00Z"
                  },
                  "verification_instructions": {
                    "record_type": "TXT",
                    "record_name": "_firma-verification.sales.acme.com",
                    "record_value": "firma-verify=abc123xyz",
                    "next_step": "Add this TXT record to your DNS, then call POST /workspace/{workspace_id}/domains/{id}/verify-ownership"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Formato de dominio inválido o el dominio ya existe",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "invalidDomain": {
                    "value": {
                      "error": "Invalid domain format",
                      "message": "Please provide a valid domain name (e.g., example.com)"
                    }
                  },
                  "domainExists": {
                    "value": {
                      "error": "Domain already exists",
                      "message": "This domain is already configured for this workspace"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "createWorkspaceDomain",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailDomains.createWorkspaceDomain({\n    workspace_id: \"workspace_id\",\n    domain: \"sales.acme.com\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/workspace/{workspace_id}/domains/{id}": {
      "get": {
        "summary": "Obtener dominio del espacio de trabajo",
        "description": "Obtiene los detalles de un dominio específico en un espacio de trabajo, incluyendo el estado de verificación y los registros DNS",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID del espacio de trabajo"
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID del dominio"
          }
        ],
        "responses": {
          "200": {
            "description": "Dominio obtenido correctamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Domain"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "getWorkspaceDomain",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailDomains.getWorkspaceDomain({\n    workspace_id: \"workspace_id\",\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      },
      "delete": {
        "summary": "Eliminar dominio del espacio de trabajo",
        "description": "Elimina un dominio del espacio de trabajo. Si el dominio es el principal o el único, el envío vuelve al remitente de la empresa o al predeterminado.",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID del espacio de trabajo"
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID del dominio"
          }
        ],
        "responses": {
          "200": {
            "description": "Dominio eliminado correctamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DomainDeleteResponse"
                },
                "example": {
                  "message": "Domain deleted successfully",
                  "domain_id": "123e4567-e89b-12d3-a456-426614174000"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "deleteWorkspaceDomain",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailDomains.deleteWorkspaceDomain({\n    workspace_id: \"workspace_id\",\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/workspace/{workspace_id}/domains/{id}/verify-ownership": {
      "post": {
        "summary": "Verificar propiedad del dominio del espacio de trabajo",
        "description": "Verifica la propiedad del dominio comprobando el registro TXT. Llama a esto después de agregar el registro TXT de verificación a tu DNS. La propagación del DNS puede tardar hasta 48 horas, pero normalmente se completa en minutos.",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID del espacio de trabajo"
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID del dominio"
          }
        ],
        "responses": {
          "200": {
            "description": "Propiedad del dominio verificada correctamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DomainVerifyOwnershipResponse"
                },
                "example": {
                  "message": "Domain ownership verified",
                  "domain": {
                    "id": "123e4567-e89b-12d3-a456-426614174000",
                    "domain": "sales.acme.com",
                    "verification_status": 1,
                    "domain_status": 0
                  },
                  "next_step": "Call POST /workspace/{workspace_id}/domains/{id}/finalize to complete domain setup and receive DNS records for email sending"
                }
              }
            }
          },
          "400": {
            "description": "La verificación falló",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "recordNotFound": {
                    "value": {
                      "error": "Verification failed",
                      "message": "TXT record not found. Please ensure the record is added correctly and DNS has propagated.",
                      "details": {
                        "expected_record": "_firma-verification.sales.acme.com",
                        "expected_value": "firma-verify=abc123xyz"
                      }
                    }
                  },
                  "alreadyVerified": {
                    "value": {
                      "error": "Already verified",
                      "message": "Domain ownership has already been verified"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "verifyWorkspaceDomainOwnership",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailDomains.verifyWorkspaceDomainOwnership({\n    workspace_id: \"workspace_id\",\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/workspace/{workspace_id}/domains/{id}/finalize": {
      "post": {
        "summary": "Finalizar configuración del dominio del espacio de trabajo",
        "description": "Finaliza la configuración del dominio registrándolo con el proveedor de correo electrónico. Esto devuelve los registros DNS (SPF, DKIM, DMARC) que deben agregarse para habilitar el envío de correo electrónico. Solo se puede llamar después de que se verifique la propiedad del dominio.",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID del espacio de trabajo"
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID del dominio"
          }
        ],
        "responses": {
          "200": {
            "description": "Dominio finalizado correctamente. Agrega los registros DNS devueltos.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DomainFinalizeResponse"
                },
                "example": {
                  "message": "Domain finalized. Add the following DNS records to enable email sending.",
                  "domain": {
                    "id": "123e4567-e89b-12d3-a456-426614174000",
                    "domain": "sales.acme.com",
                    "verification_status": 2,
                    "domain_status": 0
                  },
                  "dns_records": [
                    {
                      "type": "TXT",
                      "name": "@",
                      "value": "v=spf1 include:amazonses.com ~all",
                      "ttl": "Auto",
                      "status": "pending"
                    },
                    {
                      "type": "CNAME",
                      "name": "resend._domainkey",
                      "value": "resend._domainkey.amazonses.com",
                      "ttl": "Auto",
                      "status": "pending"
                    },
                    {
                      "type": "TXT",
                      "name": "_dmarc",
                      "value": "v=DMARC1; p=none;",
                      "ttl": "Auto",
                      "status": "pending"
                    }
                  ],
                  "next_step": "Add these DNS records, then call POST /workspace/{workspace_id}/domains/{id}/verify-dns to complete verification"
                }
              }
            }
          },
          "400": {
            "description": "No se puede finalizar",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "notVerified": {
                    "value": {
                      "error": "Ownership not verified",
                      "message": "Please verify domain ownership first by calling POST /workspace/{workspace_id}/domains/{id}/verify-ownership"
                    }
                  },
                  "alreadyFinalized": {
                    "value": {
                      "error": "Already finalized",
                      "message": "Domain has already been finalized"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "finalizeWorkspaceDomain",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailDomains.finalizeWorkspaceDomain({\n    workspace_id: \"workspace_id\",\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/workspace/{workspace_id}/domains/{id}/verify-dns": {
      "post": {
        "summary": "Verificar registros DNS del dominio del espacio de trabajo",
        "description": "Verifica que todos los registros DNS requeridos (SPF, DKIM, DMARC) estén configurados correctamente. Llama a esto después de agregar todos los registros DNS del paso de finalización. Una vez verificado, el dominio queda listo para enviar correos electrónicos.",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID del Espacio de Trabajo"
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID del dominio"
          }
        ],
        "responses": {
          "200": {
            "description": "Resultado de la verificación DNS",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DomainVerifyDnsResponse"
                },
                "examples": {
                  "verified": {
                    "summary": "Todos los registros verificados",
                    "value": {
                      "verified": true,
                      "message": "Domain is fully verified and ready to send emails",
                      "domain": {
                        "id": "123e4567-e89b-12d3-a456-426614174000",
                        "domain": "sales.acme.com",
                        "verification_status": 2,
                        "domain_status": 1,
                        "is_primary": true
                      },
                      "dns_records": [
                        {
                          "type": "TXT",
                          "name": "@",
                          "value": "v=spf1 include:amazonses.com ~all",
                          "status": "verified"
                        },
                        {
                          "type": "CNAME",
                          "name": "resend._domainkey",
                          "value": "resend._domainkey.amazonses.com",
                          "status": "verified"
                        },
                        {
                          "type": "TXT",
                          "name": "_dmarc",
                          "value": "v=DMARC1; p=none;",
                          "status": "verified"
                        }
                      ]
                    }
                  },
                  "pending": {
                    "summary": "Algunos registros pendientes",
                    "value": {
                      "verified": false,
                      "message": "Some DNS records are not yet verified. Please check your DNS configuration.",
                      "domain": {
                        "id": "123e4567-e89b-12d3-a456-426614174000",
                        "domain": "sales.acme.com",
                        "verification_status": 2,
                        "domain_status": 0
                      },
                      "dns_records": [
                        {
                          "type": "TXT",
                          "name": "@",
                          "value": "v=spf1 include:amazonses.com ~all",
                          "status": "verified"
                        },
                        {
                          "type": "CNAME",
                          "name": "resend._domainkey",
                          "value": "resend._domainkey.amazonses.com",
                          "status": "pending"
                        },
                        {
                          "type": "TXT",
                          "name": "_dmarc",
                          "value": "v=DMARC1; p=none;",
                          "status": "pending"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Dominio no finalizado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "Domain not finalized",
                  "message": "Please finalize domain setup first by calling POST /workspace/{workspace_id}/domains/{id}/finalize"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "verifyWorkspaceDomainDns",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailDomains.verifyWorkspaceDomainDns({\n    workspace_id: \"workspace_id\",\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/workspace/{workspace_id}/domains/{id}/set-primary": {
      "post": {
        "summary": "Establecer dominio principal del espacio de trabajo",
        "description": "Establece un dominio como el dominio de envío principal para el espacio de trabajo. Solo los dominios completamente verificados (domain_status=1) pueden establecerse como principales.",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID del Espacio de Trabajo"
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID del dominio"
          }
        ],
        "responses": {
          "200": {
            "description": "Dominio principal actualizado correctamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DomainSetPrimaryResponse"
                },
                "example": {
                  "message": "Primary domain updated",
                  "domain": {
                    "id": "123e4567-e89b-12d3-a456-426614174000",
                    "domain": "sales.acme.com",
                    "verification_status": 2,
                    "domain_status": 1,
                    "is_primary": true
                  }
                }
              }
            }
          },
          "400": {
            "description": "Dominio no verificado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "Domain not verified",
                  "message": "Only fully verified domains can be set as primary"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        },
        "operationId": "setWorkspacePrimaryDomain",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.emailDomains.setWorkspacePrimaryDomain({\n    workspace_id: \"workspace_id\",\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/workspace/{workspace_id}/custom-fields": {
      "get": {
        "summary": "Listar campos personalizados del espacio de trabajo",
        "description": "Obtiene todas las definiciones de campos personalizados de un espacio de trabajo",
        "tags": [
          "Custom Fields"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "description": "ID del Espacio de Trabajo",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Campos personalizados obtenidos correctamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomFieldListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          }
        },
        "operationId": "listWorkspaceCustomFields",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.customFields.listWorkspaceCustomFields({\n    workspace_id: \"workspace_id\"\n});\nconsole.log(response);"
          }
        ]
      },
      "post": {
        "summary": "Crear campo personalizado del espacio de trabajo",
        "description": "Crea una nueva definición de campo personalizado para un espacio de trabajo",
        "tags": [
          "Custom Fields"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "description": "ID del Espacio de Trabajo",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "field_label"
                ],
                "properties": {
                  "field_label": {
                    "type": "string",
                    "description": "Etiqueta visible (1-100 caracteres)",
                    "maxLength": 100
                  },
                  "field_name": {
                    "type": "string",
                    "description": "Nombre legible por máquina opcional (se genera automáticamente a partir de la etiqueta si no se proporciona)",
                    "maxLength": 50
                  },
                  "is_preset": {
                    "type": "boolean",
                    "description": "Si es true, el campo tiene un valor preestablecido para todos los usuarios",
                    "default": false
                  },
                  "preset_value": {
                    "type": "string",
                    "description": "Valor preestablecido (máximo 500 caracteres, solo se usa cuando is_preset=true)",
                    "maxLength": 500
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Campo personalizado creado correctamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkspaceCustomField"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "409": {
            "description": "Conflicto - Ya existe un campo personalizado con este nombre",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "createWorkspaceCustomField",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.customFields.createWorkspaceCustomField({\n    workspace_id: \"workspace_id\",\n    field_label: \"field_label\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/workspace/{workspace_id}/custom-fields/{field_id}": {
      "put": {
        "summary": "Actualizar campo personalizado del espacio de trabajo",
        "description": "Actualiza una definición de campo personalizado existente",
        "tags": [
          "Custom Fields"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "field_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "field_label": {
                    "type": "string",
                    "maxLength": 100
                  },
                  "is_preset": {
                    "type": "boolean"
                  },
                  "preset_value": {
                    "type": "string",
                    "maxLength": 500
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Campo personalizado actualizado correctamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkspaceCustomField"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "409": {
            "description": "Conflicto - Ya existe un campo personalizado con este nombre",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "updateWorkspaceCustomField",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.customFields.updateWorkspaceCustomField({\n    workspace_id: \"workspace_id\",\n    field_id: \"field_id\"\n});\nconsole.log(response);"
          }
        ]
      },
      "delete": {
        "summary": "Eliminar campo personalizado del espacio de trabajo",
        "description": "Elimina (soft-delete) una definición de campo personalizado",
        "tags": [
          "Custom Fields"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "field_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Campo personalizado eliminado correctamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          }
        },
        "operationId": "deleteWorkspaceCustomField",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.customFields.deleteWorkspaceCustomField({\n    workspace_id: \"workspace_id\",\n    field_id: \"field_id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/templates/{template_id}/custom-fields": {
      "get": {
        "summary": "Listar campos personalizados de la plantilla",
        "description": "Obtiene todas las definiciones de campos personalizados de una plantilla",
        "tags": [
          "Custom Fields"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "template_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Campos personalizados obtenidos correctamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomFieldListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          }
        },
        "operationId": "listTemplateCustomFields",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.customFields.listTemplateCustomFields({\n    template_id: \"template_id\"\n});\nconsole.log(response);"
          }
        ]
      },
      "post": {
        "summary": "Crear campo personalizado de la plantilla",
        "description": "Crea una nueva definición de campo personalizado para una plantilla",
        "tags": [
          "Custom Fields"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "template_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "field_label"
                ],
                "properties": {
                  "field_label": {
                    "type": "string",
                    "maxLength": 100
                  },
                  "field_name": {
                    "type": "string",
                    "maxLength": 50
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Campo personalizado creado correctamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateCustomField"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "409": {
            "description": "Conflicto - Ya existe un campo personalizado con este nombre",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "createTemplateCustomField",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.customFields.createTemplateCustomField({\n    template_id: \"template_id\",\n    field_label: \"field_label\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/templates/{template_id}/custom-fields/{field_id}": {
      "delete": {
        "summary": "Eliminar campo personalizado de la plantilla",
        "description": "Elimina (soft-delete) una definición de campo personalizado de una plantilla",
        "tags": [
          "Custom Fields"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "template_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "field_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Campo personalizado eliminado correctamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          }
        },
        "operationId": "deleteTemplateCustomField",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.customFields.deleteTemplateCustomField({\n    template_id: \"template_id\",\n    field_id: \"field_id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/signing-requests/{request_id}/custom-fields": {
      "get": {
        "summary": "Listar campos personalizados de la solicitud de firma",
        "description": "Obtiene todas las definiciones de campos personalizados de una solicitud de firma",
        "tags": [
          "Custom Fields"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "request_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Campos personalizados obtenidos correctamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomFieldListResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          }
        },
        "operationId": "listSigningRequestCustomFields",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.customFields.listSigningRequestCustomFields({\n    request_id: \"request_id\"\n});\nconsole.log(response);"
          }
        ]
      },
      "post": {
        "summary": "Crear campo personalizado de la solicitud de firma",
        "description": "Crea una nueva definición de campo personalizado para una solicitud de firma",
        "tags": [
          "Custom Fields"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "request_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "field_label"
                ],
                "properties": {
                  "field_label": {
                    "type": "string",
                    "maxLength": 100
                  },
                  "field_name": {
                    "type": "string",
                    "maxLength": 50
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Campo personalizado creado correctamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SigningRequestCustomField"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          },
          "409": {
            "description": "Conflicto - Ya existe un campo personalizado con este nombre",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "createSigningRequestCustomField",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.customFields.createSigningRequestCustomField({\n    request_id: \"request_id\",\n    field_label: \"field_label\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/signing-requests/{request_id}/custom-fields/{field_id}": {
      "delete": {
        "summary": "Eliminar campo personalizado de la solicitud de firma",
        "description": "Elimina (soft-delete) una definición de campo personalizado de una solicitud de firma",
        "tags": [
          "Custom Fields"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "request_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "field_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Campo personalizado eliminado correctamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "$ref": "#/components/responses/NotFoundError"
          }
        },
        "operationId": "deleteSigningRequestCustomField",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.customFields.deleteSigningRequestCustomField({\n    request_id: \"request_id\",\n    field_id: \"field_id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/workspaces/{id}/webhooks/rotate-secret": {
      "post": {
        "summary": "Rotar secreto de webhook del espacio de trabajo",
        "description": "Genera un nuevo secreto de firma de webhook para el espacio de trabajo. El secreto anterior sigue siendo válido durante 7 días.",
        "operationId": "rotateWorkspaceWebhookSecret",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID del Espacio de Trabajo",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Secreto rotado correctamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RotateSecretResponse"
                }
              }
            }
          },
          "429": {
            "description": "Período de espera activo — el secreto se rotó recientemente"
          }
        },
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.webhooks.rotateWorkspaceWebhookSecret({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/workspaces/{id}/webhooks/secret-status": {
      "get": {
        "summary": "Obtener estado del secreto de webhook del espacio de trabajo",
        "description": "Devuelve el estado del secreto de webhook del espacio de trabajo, incluyendo la fecha de creación, la fecha de rotación y el estado del período de gracia.",
        "operationId": "getWorkspaceWebhookSecretStatus",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID del Espacio de Trabajo",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Estado del secreto obtenido",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SecretStatusResponse"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.webhooks.getWorkspaceWebhookSecretStatus({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/signing-requests/{id}/download": {
      "get": {
        "summary": "Descargar Documento de la Solicitud de Firma",
        "description": "Recupera una URL de descarga para el documento firmado de una solicitud de firma. Para solicitudes de firma completadas, devuelve el PDF firmado final. Para solicitudes de firma en curso donde la descarga parcial está habilitada, devuelve una URL al documento parcialmente firmado generado en el momento en que el último firmante completó su firma.\n\n**Descargas parciales:** Las descargas parciales solo están disponibles cuando la solicitud de firma tiene `allow_partial_download` habilitado en su configuración. Si el documento aún no se ha generado parcialmente, se devuelve un `503`; reintenta después del intervalo indicado en `Retry-After`.\n\n**Expiración de la URL:** `download_url` es una URL prefirmada que expira. La marca de tiempo de expiración se proporciona en `expires_at`.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID de la solicitud de firma",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "URL de descarga obtenida correctamente.",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Límite de tasa: 200 solicitudes por minuto"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SigningRequestDownloadResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "description": "Solicitud de firma no encontrada.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "not_found"
                }
              }
            }
          },
          "409": {
            "description": "La solicitud de firma aún no ha sido enviada. La descarga solo está disponible después de que se haya enviado la solicitud.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "no_document_available",
                  "message": "Signing request has not been sent yet"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          },
          "503": {
            "description": "La generación del documento está en progreso. Reintenta después del intervalo indicado.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Segundos a esperar antes de reintentar"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "generation_timeout": {
                    "summary": "La generación del documento agotó el tiempo de espera",
                    "value": {
                      "error": "generation_timeout"
                    }
                  },
                  "stale_at_publication": {
                    "summary": "El documento estaba desactualizado en el momento de la publicación",
                    "value": {
                      "error": "stale_at_publication"
                    }
                  }
                }
              }
            }
          }
        },
        "operationId": "downloadSigningRequest",
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signingRequests.downloadSigningRequest({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/signing-requests/{id}/signers/{signer_id}/signature": {
      "get": {
        "operationId": "retrieveSignerSignature",
        "summary": "Recuperar la Imagen de Firma del Firmante",
        "description": "Recupera la firma adoptada de un firmante como un data URI en PNG base64, independiente del PDF firmado. Un firmante adopta una firma que se aplica a todos sus campos de firma, así que no se necesita field_id. Las firmas dibujadas devuelven la imagen capturada; las firmas escritas se renderizan a PNG en el servidor. El `image` es un URI `data:image/png;base64,...` que se puede usar directamente en un `<img src>`. Por defecto se superpone un marco de identificación del firmante (`include_frame=false` para omitirlo). Cada recuperación exitosa queda registrada en el registro de auditoría. Límite de 60/min. La validez legal recae en el PDF sellado y el certificado de finalización, no en esta imagen.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID de la solicitud de firma",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "signer_id",
            "in": "path",
            "required": true,
            "description": "ID del firmante (destinatario) — el recipient_id de GET /fields",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "include_frame",
            "in": "query",
            "required": false,
            "description": "Superponer el marco de identificación del firmante en la imagen (por defecto true). Poner en false para la marca sin adornos.",
            "schema": {
              "type": "boolean",
              "default": true
            }
          }
        ],
        "responses": {
          "200": {
            "description": "La marca del firmante como un data URI en PNG base64.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "signer_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "kind": {
                      "type": "string",
                      "enum": [
                        "signature",
                        "initials",
                        "stamp"
                      ]
                    },
                    "format": {
                      "type": "string",
                      "example": "png"
                    },
                    "framed": {
                      "type": "boolean",
                      "description": "Si se superpuso el marco de identificación del firmante."
                    },
                    "image": {
                      "type": "string",
                      "description": "PNG como un data URI.",
                      "example": "data:image/png;base64,iVBORw0KGgo..."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Clave API faltante o inválida.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Solicitud de firma/firmante/campo no encontrado o no pertenece a tu espacio de trabajo (NOT_FOUND), o no se capturó ninguna marca (SIGNATURE_NOT_AVAILABLE).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Límite de solicitudes excedido (60/min para la recuperación de firmas).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "El renderizado falló (RENDER_FAILED) o la escritura obligatoria del registro de auditoría de acceso falló (AUDIT_WRITE_FAILED); no se devuelve ninguna imagen.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signingRequests.retrieveSignerSignature({\n    id: \"id\",\n    signer_id: \"signer_id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/signing-requests/{id}/signers/{signer_id}/initials": {
      "get": {
        "operationId": "retrieveSignerInitials",
        "summary": "Recuperar la Imagen de Iniciales del Firmante",
        "description": "Recupera las iniciales adoptadas de un firmante como un data URI en PNG base64. Una sola marca de iniciales por firmante (sin field_id). Misma forma de respuesta, encuadre, auditoría y límite de solicitudes que el endpoint de firma.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID de la solicitud de firma",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "signer_id",
            "in": "path",
            "required": true,
            "description": "ID del firmante (destinatario)",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "include_frame",
            "in": "query",
            "required": false,
            "description": "Superponer el marco de identificación del firmante en la imagen (por defecto true). Poner en false para la marca sin adornos.",
            "schema": {
              "type": "boolean",
              "default": true
            }
          }
        ],
        "responses": {
          "200": {
            "description": "La marca del firmante como un data URI en PNG base64.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "signer_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "kind": {
                      "type": "string",
                      "enum": [
                        "signature",
                        "initials",
                        "stamp"
                      ]
                    },
                    "format": {
                      "type": "string",
                      "example": "png"
                    },
                    "framed": {
                      "type": "boolean",
                      "description": "Si se superpuso el marco de identificación del firmante."
                    },
                    "image": {
                      "type": "string",
                      "description": "PNG como un data URI.",
                      "example": "data:image/png;base64,iVBORw0KGgo..."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Clave API faltante o inválida.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Solicitud de firma/firmante/campo no encontrado o no pertenece a tu espacio de trabajo (NOT_FOUND), o no se capturó ninguna marca (SIGNATURE_NOT_AVAILABLE).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Límite de solicitudes excedido (60/min para la recuperación de firmas).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "El renderizado falló (RENDER_FAILED) o la escritura obligatoria del registro de auditoría de acceso falló (AUDIT_WRITE_FAILED); no se devuelve ninguna imagen.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signingRequests.retrieveSignerInitials({\n    id: \"id\",\n    signer_id: \"signer_id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/signing-requests/{id}/signers/{signer_id}/stamps/{field_id}": {
      "get": {
        "operationId": "retrieveSignerStamp",
        "summary": "Recuperar la Imagen de Sello del Firmante",
        "description": "Recupera el sello de un firmante para un campo de sello específico como un data URI en PNG base64. Los sellos son por campo, así que se requiere `field_id` (obtenlo de GET /signing-requests/{id}/fields, filtrando por type=stamp). Mismo encuadre, auditoría y límite de 60/min.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID de la solicitud de firma",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "signer_id",
            "in": "path",
            "required": true,
            "description": "ID del firmante (destinatario)",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "field_id",
            "in": "path",
            "required": true,
            "description": "ID del campo de sello",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "include_frame",
            "in": "query",
            "required": false,
            "description": "Superponer el marco de identificación del firmante en la imagen (por defecto true). Poner en false para la marca sin adornos.",
            "schema": {
              "type": "boolean",
              "default": true
            }
          }
        ],
        "responses": {
          "200": {
            "description": "La marca del firmante como un data URI en PNG base64.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "signer_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "kind": {
                      "type": "string",
                      "enum": [
                        "signature",
                        "initials",
                        "stamp"
                      ]
                    },
                    "format": {
                      "type": "string",
                      "example": "png"
                    },
                    "framed": {
                      "type": "boolean",
                      "description": "Si se superpuso el marco de identificación del firmante."
                    },
                    "image": {
                      "type": "string",
                      "description": "PNG como un data URI.",
                      "example": "data:image/png;base64,iVBORw0KGgo..."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "El campo no es del tipo esperado (INVALID_FIELD_TYPE).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Clave API faltante o inválida.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Solicitud de firma/firmante/campo no encontrado o no pertenece a tu espacio de trabajo (NOT_FOUND), o no se capturó ninguna marca (SIGNATURE_NOT_AVAILABLE).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Límite de solicitudes excedido (60/min para la recuperación de firmas).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "El renderizado falló (RENDER_FAILED) o la escritura obligatoria del registro de auditoría de acceso falló (AUDIT_WRITE_FAILED); no se devuelve ninguna imagen.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signingRequests.retrieveSignerStamp({\n    id: \"id\",\n    signer_id: \"signer_id\",\n    field_id: \"field_id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/signing-requests/{id}/signers/{signer_id}/files/{field_id}": {
      "get": {
        "operationId": "retrieveSignerFile",
        "summary": "Recuperar Archivo Subido por el Firmante",
        "description": "Recupera un archivo que un firmante subió a un campo de archivo. Devuelve una URL de descarga prefirmada de corta duración (300s), no los bytes. Se requiere `field_id` (de GET /signing-requests/{id}/fields, filtrando por type=file). Cada recuperación queda registrada en el registro de auditoría; límite de 60/min. Descarga el archivo cuanto antes en el servidor antes de que la URL expire.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID de la solicitud de firma",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "signer_id",
            "in": "path",
            "required": true,
            "description": "ID del firmante (destinatario)",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "field_id",
            "in": "path",
            "required": true,
            "description": "ID del campo de archivo",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Una URL de descarga prefirmada de corta duración para el archivo subido por el firmante.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "signer_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "kind": {
                      "type": "string",
                      "example": "file"
                    },
                    "file_name": {
                      "type": "string",
                      "nullable": true
                    },
                    "file_type": {
                      "type": "string",
                      "nullable": true
                    },
                    "file_size": {
                      "type": "integer",
                      "nullable": true
                    },
                    "url": {
                      "type": "string",
                      "description": "URL de descarga prefirmada."
                    },
                    "expires_in": {
                      "type": "integer",
                      "example": 300,
                      "description": "Segundos hasta que la URL expire."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "El campo no es un campo de archivo (INVALID_FIELD_TYPE).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Clave API faltante o inválida.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "No encontrado / no está en tu espacio de trabajo (NOT_FOUND) o no se subió ningún archivo (SIGNATURE_NOT_AVAILABLE).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Límite de solicitudes excedido (60/min).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Falló la generación de la URL firmada (INTERNAL_ERROR) o falló la escritura de auditoría de acceso requerida (AUDIT_WRITE_FAILED); no se devuelve ninguna URL.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signingRequests.retrieveSignerFile({\n    id: \"id\",\n    signer_id: \"signer_id\",\n    field_id: \"field_id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/company/logo": {
      "post": {
        "tags": [
          "Company"
        ],
        "summary": "Subir Logo de la Empresa",
        "description": "Sube una imagen de logo para la empresa. Acepta PNG o JPEG, máximo 2MB. Reemplaza cualquier logo existente.",
        "operationId": "uploadCompanyLogo",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "Archivo de imagen del logo (PNG o JPEG, máximo 2MB)"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Logo subido correctamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LogoUploadResponse"
                }
              }
            }
          },
          "400": {
            "description": "Archivo inválido (formato incorrecto, demasiado grande o faltante)"
          }
        },
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import * as fs from \"fs\";\nimport { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.company.uploadCompanyLogo({\n    file: fs.createReadStream(\"/path/to/your/file\")\n});\nconsole.log(response);"
          }
        ]
      },
      "delete": {
        "tags": [
          "Company"
        ],
        "summary": "Eliminar Logo de la Empresa",
        "description": "Elimina el logo de la empresa. Los certificados usarán el logo predeterminado de Firma.",
        "operationId": "deleteCompanyLogo",
        "responses": {
          "200": {
            "description": "Logo eliminado correctamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LogoDeleteResponse"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.company.deleteCompanyLogo();\nconsole.log(response);"
          }
        ]
      }
    },
    "/workspaces/{id}/logo": {
      "post": {
        "tags": [
          "Workspaces"
        ],
        "summary": "Subir Logo del Espacio de Trabajo",
        "description": "Sube un logo para un espacio de trabajo específico. Anula el logo de la empresa en los certificados y correos electrónicos de este espacio de trabajo. Acepta PNG o JPEG, máximo 2MB.",
        "operationId": "uploadWorkspaceLogo",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID del espacio de trabajo"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "Archivo de imagen del logo (PNG o JPEG, máximo 2MB)"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Logo subido correctamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LogoUploadResponse"
                }
              }
            }
          },
          "400": {
            "description": "Archivo inválido (formato incorrecto, demasiado grande o faltante)"
          }
        },
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import * as fs from \"fs\";\nimport { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.workspaces.uploadWorkspaceLogo({\n    file: fs.createReadStream(\"/path/to/your/file\"),\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      },
      "delete": {
        "tags": [
          "Workspaces"
        ],
        "summary": "Eliminar Logo del Espacio de Trabajo",
        "description": "Elimina el logo del espacio de trabajo. Los certificados volverán a usar el logo de la empresa, o el predeterminado de Firma.",
        "operationId": "deleteWorkspaceLogo",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID del espacio de trabajo"
          }
        ],
        "responses": {
          "200": {
            "description": "Logo eliminado correctamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LogoDeleteResponse"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.workspaces.deleteWorkspaceLogo({\n    id: \"id\"\n});\nconsole.log(response);"
          }
        ]
      }
    },
    "/documents": {
      "post": {
        "summary": "Subir un documento",
        "description": "Solicita una URL de subida prefirmada para un documento. Sube el archivo directamente a la URL devuelta, luego pasa el document_id al crear una solicitud de firma. Usa esto para documentos mayores a 5MB que excedan el límite de tamaño de solicitud en base64 en línea.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "operationId": "uploadDocument",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "file_name",
                  "file_size",
                  "content_type"
                ],
                "properties": {
                  "file_name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Nombre del archivo del documento",
                    "example": "contract.pdf"
                  },
                  "file_size": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 52428800,
                    "description": "Tamaño del archivo en bytes. Máximo 50MB (52,428,800 bytes).",
                    "example": 15000000
                  },
                  "content_type": {
                    "type": "string",
                    "enum": [
                      "application/pdf",
                      "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
                    ],
                    "description": "Tipo MIME del documento",
                    "example": "application/pdf"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "URL de subida creada",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "document_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "ID del documento a pasar en la solicitud de firma"
                    },
                    "upload_url": {
                      "type": "string",
                      "format": "uri",
                      "description": "URL prefirmada para hacer PUT del archivo del documento. Envía los bytes del archivo en bruto con el Content-Type coincidiendo con el content_type solicitado."
                    },
                    "upload_token": {
                      "type": "string",
                      "description": "Token de autenticación de subida (incluido en el upload_url)"
                    },
                    "expires_in": {
                      "type": "integer",
                      "description": "Segundos hasta que la URL de subida expire",
                      "example": 3600
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error de validación (file_size, content_type inválidos, etc.)"
          },
          "401": {
            "description": "Clave API inválida o faltante"
          }
        },
        "x-codeSamples": [
          {
            "lang": "TypeScript",
            "label": "@firma-dev/sdk",
            "source": "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.signingRequests.uploadDocument({\n    file_name: \"contract.pdf\",\n    file_size: 15000000,\n    content_type: \"application/pdf\"\n});\nconsole.log(response);"
          }
        ]
      }
    }
  }
}
