{
  "openapi": "3.0.3",
  "info": {
    "title": "API de Socios de Firma",
    "description": "API RESTful para firma de documentos y gesti\u00f3n de plantillas.\n\n**Autenticaci\u00f3n**: Todos los endpoints requieren autenticaci\u00f3n mediante clave API a trav\u00e9s del encabezado `Authorization`. Usa tu clave API directamente sin ning\u00fan prefijo (por ejemplo, `your-api-key`). El prefijo Bearer es opcional pero no obligatorio.\n\n**Caracter\u00edsticas de Seguridad**:\n- Validaci\u00f3n 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\u00edmite de Solicitudes**: Los l\u00edmites de solicitudes est\u00e1n escalonados seg\u00fan el tipo de operaci\u00f3n:\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\u00f3n/expiraci\u00f3n de clave API: 1 solicitud por minuto\n- Rotaci\u00f3n de secreto de webhook: 1 solicitud por minuto\n\nCuando se superan los l\u00edmites de solicitudes, la API devuelve una respuesta `429 Too Many Requests` con los encabezados:\n- `X-RateLimit-Limit`: M\u00e1ximo 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\u00e1ndo se restablece el l\u00edmite\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\u00e1quina) y `details` (errores de validaci\u00f3n a nivel de campo cuando corresponda).\n\n**Integraci\u00f3n del Editor de Plantillas Incrustado**: El Editor de Plantillas de Firma se puede incrustar en tu aplicaci\u00f3n 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\u00eda 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.35.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\u00f3n - Recomendada (Actual)"
    },
    {
      "url": "https://api.firma.dev/api/v1",
      "description": "API de Producci\u00f3n - Planeada"
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    }
  ],
  "tags": [
    {
      "name": "Company",
      "description": "Informaci\u00f3n y configuraci\u00f3n de la empresa"
    },
    {
      "name": "Workspaces",
      "description": "Operaciones de gesti\u00f3n de espacios de trabajo"
    },
    {
      "name": "Templates",
      "description": "Operaciones de gesti\u00f3n de plantillas"
    },
    {
      "name": "Signing Requests",
      "description": "Operaciones de solicitudes de firma de documentos"
    },
    {
      "name": "Custom Fields",
      "description": "Gesti\u00f3n de definiciones de campos personalizados para espacios de trabajo, plantillas y solicitudes de firma"
    },
    {
      "name": "Webhooks",
      "description": "Configuraci\u00f3n y gesti\u00f3n de webhooks"
    },
    {
      "name": "JWT Management",
      "description": "Generaci\u00f3n y revocaci\u00f3n de tokens JWT para plantillas incrustadas"
    },
    {
      "name": "Workspace Settings",
      "description": "Configuraci\u00f3n y ajustes del espacio de trabajo"
    },
    {
      "name": "Email Domains",
      "description": "Configuraci\u00f3n y verificaci\u00f3n de dominios de correo electr\u00f3nico para enviar correos de solicitudes de firma desde dominios personalizados"
    },
    {
      "name": "Email Templates",
      "description": "Gesti\u00f3n de plantillas de correo electr\u00f3nico para personalizaci\u00f3n de notificaciones de solicitudes de firma a nivel de espacio de trabajo y de empresa"
    },
    {
      "name": "Signer Terms",
      "description": "T\u00e9rminos de servicio / declaraciones de consentimiento personalizadas del firmante, a nivel de empresa con anulaciones por espacio de trabajo seg\u00fan el idioma"
    }
  ],
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "Authorization",
        "description": "Clave API para autenticaci\u00f3n. Usa tu clave API directamente sin ning\u00fan prefijo (por ejemplo, 'your-api-key'). El prefijo Bearer es opcional pero no obligatorio."
      }
    },
    "responses": {
      "ValidationError": {
        "description": "Solicitud Incorrecta - La validaci\u00f3n fall\u00f3",
        "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\u00e1lida 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\u00f3 el l\u00edmite de solicitudes",
        "headers": {
          "X-RateLimit-Limit": {
            "schema": {
              "type": "integer"
            },
            "description": "N\u00famero m\u00e1ximo 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\u00f1adir nuevo destinatario",
                "value": {
                  "recipient": {
                    "first_name": "Jane",
                    "last_name": "Doe",
                    "email": "jane@example.com",
                    "designation": "Signer",
                    "order": 2
                  }
                }
              },
              "add-date-field": {
                "summary": "A\u00f1adir 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\u00f1adir campo de solo lectura con valor est\u00e1tico",
                "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\u00f1adir campo de solo lectura con datos del destinatario",
                "description": "Crea un campo de texto que se autocompleta con el correo electr\u00f3nico 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\u00f3n 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\u00f3n completa que a\u00f1ade 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 \u00fanico 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",
              "cs",
              "sv",
              "nl",
              "ro",
              "nb"
            ],
            "default": "en"
          },
          "account_owner": {
            "type": "string",
            "description": "Nombre del propietario de la cuenta",
            "maxLength": 255
          },
          "account_owner_email": {
            "type": "string",
            "format": "email",
            "description": "Direcci\u00f3n de correo electr\u00f3nico 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\u00fablico 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\u00e9ditos 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\u00f3n de la cuenta de la empresa"
          },
          "updated_date": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de la \u00faltima actualizaci\u00f3n 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 \u00fanico 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\u00e9ditos 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\u00f3n del espacio de trabajo"
          },
          "updated_date": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de la \u00faltima actualizaci\u00f3n del espacio de trabajo"
          },
          "webhook_enabled": {
            "type": "boolean",
            "description": "Indica si los webhooks a nivel de espacio de trabajo est\u00e1n 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 \u00faltima rotaci\u00f3n del secreto de webhook",
            "nullable": true
          },
          "webhook_secret_created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de cuando se cre\u00f3 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\u00fablico a la imagen del logo del espacio de trabajo. Devuelve el logo espec\u00edfico del espacio de trabajo, o null si no est\u00e1 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 \u00fanico de la plantilla"
          },
          "name": {
            "type": "string",
            "description": "Nombre de la plantilla",
            "maxLength": 255
          },
          "description": {
            "type": "string",
            "description": "Descripci\u00f3n 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\u00f3n. Las URLs iniciales son v\u00e1lidas por 7 d\u00edas; las URLs renovadas son v\u00e1lidas por 1 hora. Solicita una nueva recuperaci\u00f3n 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\u00e1ndo expirar\u00e1 document_url. Despu\u00e9s de este momento, la URL devolver\u00e1 un error de acceso denegado. Vuelve a obtener la plantilla para recibir una nueva URL firmada."
          },
          "page_count": {
            "type": "integer",
            "minimum": 1,
            "description": "N\u00famero de p\u00e1ginas 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\u00famero de cr\u00e9ditos consumidos cuando se env\u00eda una solicitud de firma desde esta plantilla. El valor m\u00ednimo 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\u00f3n de la plantilla"
          },
          "updated_date": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de la \u00faltima actualizaci\u00f3n de la plantilla"
          }
        },
        "required": [
          "id",
          "name",
          "created_date"
        ]
      },
      "TemplateUser": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identificador \u00fanico del usuario de la plantilla"
          },
          "name": {
            "type": "string",
            "description": "Nombre del destinatario (nombre y apellido combinados)"
          },
          "email": {
            "type": "string",
            "format": "email",
            "description": "Direcci\u00f3n de correo electr\u00f3nico 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\u00f3n, 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\u00famero de tel\u00e9fono del destinatario"
          },
          "street_address": {
            "type": "string",
            "nullable": true,
            "description": "Direcci\u00f3n 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\u00f3digo postal del destinatario"
          },
          "country": {
            "type": "string",
            "nullable": true,
            "description": "Pa\u00eds 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\u00edo (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\u00e1n vac\u00edos 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\u00f3n del campo personalizado (por ejemplo, 'artist_name'). Solo est\u00e1 presente para campos vinculados a una definici\u00f3n 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\u00f3mo deben mostrarse y formatearse los valores de fecha.",
        "properties": {
          "dateFormat": {
            "type": "string",
            "description": "Patr\u00f3n de formato de fecha. Usa formatos predefinidos o patrones personalizados con: yyyy (a\u00f1o de 4 d\u00edgitos), MM (mes de 2 d\u00edgitos), dd (d\u00eda de 2 d\u00edgitos), 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"
          },
          "fontSize": {
            "type": "integer",
            "minimum": 8,
            "maximum": 48,
            "description": "Tama\u00f1o de fuente inicial/m\u00e1ximo opcional en p\u00edxeles para el valor del campo renderizado. El texto se reduce autom\u00e1ticamente para ajustarse al recuadro del campo. Om\u00edtelo para el dimensionado autom\u00e1tico. Los valores fuera de 8-48 se limitan a ese rango."
          }
        },
        "example": {
          "dateFormat": "MMMM dd, yyyy"
        }
      },
      "TextFormatRules": {
        "type": "object",
        "description": "Reglas de formato para campos con texto (text, textarea, email, name, phone, company, title, number, dropdown, url).",
        "properties": {
          "fontSize": {
            "type": "integer",
            "minimum": 8,
            "maximum": 48,
            "description": "Tama\u00f1o de fuente inicial/m\u00e1ximo opcional en p\u00edxeles para el valor del campo renderizado, aplicado en la vista de firma y en el PDF sellado. El texto se reduce autom\u00e1ticamente para ajustarse al recuadro del campo, por lo que el tama\u00f1o expl\u00edcito es un l\u00edmite superior, no una garant\u00eda. Om\u00edtelo para el dimensionado autom\u00e1tico (base predeterminada de 14 px). Los valores fuera de 8-48 se limitan a ese rango; los valores no num\u00e9ricos se ignoran. No se aplica a los campos signature, initials, checkbox, radio, file ni stamp."
          }
        },
        "example": {
          "fontSize": 12
        }
      },
      "FileFormatRules": {
        "type": "object",
        "description": "Reglas de formato para campos de carga de archivos. Especifica qu\u00e9 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\u00e1gicos (magic bytes), no solo por la extensi\u00f3n. El tama\u00f1o m\u00e1ximo de archivo es 10MB."
          }
        },
        "example": {
          "acceptedFileTypes": "image_and_pdf"
        }
      },
      "FieldValidationRules": {
        "type": "object",
        "nullable": true,
        "description": "Reglas de validaci\u00f3n para valores de campo. Reservado para uso futuro: actualmente no se aplica a ning\u00fan 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 \u00fanico 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\u00f3n del campo personalizado (por ejemplo, 'artist_name'). Solo est\u00e1 presente para campos vinculados a una definici\u00f3n de campo personalizado; de lo contrario es null."
          },
          "position": {
            "type": "object",
            "description": "Posici\u00f3n y dimensiones del campo en el documento. Todos los valores son porcentajes (0-100). El campo debe caber dentro de la p\u00e1gina: x + width <= 100 y y + height <= 100.",
            "properties": {
              "x": {
                "type": "number",
                "minimum": 0,
                "maximum": 100,
                "description": "Coordenada X de la posici\u00f3n del campo (porcentaje, 0-100)"
              },
              "y": {
                "type": "number",
                "minimum": 0,
                "maximum": 100,
                "description": "Coordenada Y de la posici\u00f3n 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\u00famero de p\u00e1gina donde se encuentra el campo (empieza en 1). No debe superar el total de p\u00e1ginas 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\u00f3n o bot\u00f3n de opci\u00f3n entre s\u00ed. Los campos que comparten el mismo multi_group_id se comportan como un grupo mutuamente excluyente (como botones de opci\u00f3n): seleccionar uno deselecciona autom\u00e1ticamente los dem\u00e1s del grupo. Usa el mismo UUID en varios campos para crear un grupo donde solo se puede seleccionar una opci\u00f3n 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\u00f3n"
          },
          "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\u00e1tico para campos de solo lectura"
          }
        },
        "required": [
          "id",
          "type",
          "page_number"
        ]
      },
      "Reminder": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identificador \u00fanico del recordatorio"
          },
          "hours": {
            "type": "integer",
            "minimum": 1,
            "description": "Horas despu\u00e9s del env\u00edo antes de que se env\u00ede 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\u00edfico al que se le enviar\u00e1 el recordatorio (usado en el contexto de plantilla)"
          },
          "recipient_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "Destinatario espec\u00edfico al que se le enviar\u00e1 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\u00e1ndo se envi\u00f3 realmente el recordatorio"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de creaci\u00f3n del recordatorio"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de la \u00faltima actualizaci\u00f3n 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 \u00fanico de la solicitud de firma"
          },
          "name": {
            "type": "string",
            "description": "Nombre de la solicitud de firma",
            "maxLength": 255
          },
          "description": {
            "type": "string",
            "nullable": true,
            "description": "Descripci\u00f3n 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\u00f3n. Las URLs iniciales son v\u00e1lidas por 7 d\u00edas; las URLs renovadas son v\u00e1lidas por 1 hora. Solicita una nueva recuperaci\u00f3n 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\u00e1ndo expirar\u00e1 document_url. Despu\u00e9s de este momento, la URL devolver\u00e1 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\u00famero de p\u00e1ginas 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\u00edas)"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Marca de tiempo ISO 8601 de cu\u00e1ndo expira la solicitud de firma. Se calcula a partir de sent_date + expiration_hours. Es nulo si la solicitud de firma a\u00fan no ha sido enviada o no tiene expiration_hours configurado."
          },
          "credit_cost": {
            "type": "integer",
            "minimum": 1,
            "default": 1,
            "description": "N\u00famero de cr\u00e9ditos consumidos cuando se envi\u00f3 esta solicitud de firma. El valor m\u00ednimo es 1."
          },
          "template_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID de la plantilla si se cre\u00f3 a partir de una plantilla"
          },
          "settings": {
            "$ref": "#/components/schemas/SigningRequestSettings"
          },
          "created_date": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de creaci\u00f3n"
          },
          "updated_date": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de la \u00faltima actualizaci\u00f3n"
          },
          "sent_date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Cu\u00e1ndo se envi\u00f3 la solicitud de firma"
          },
          "finished_date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Cu\u00e1ndo se completaron todas las firmas"
          },
          "cancelled_date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Cu\u00e1ndo se cancel\u00f3 la solicitud de firma"
          },
          "declined_date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Cu\u00e1ndo se rechaz\u00f3 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\u00f3n 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\u00f3n del campo personalizado (por ejemplo, 'artist_name'). Solo est\u00e1 presente para campos vinculados a una definici\u00f3n 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\u00e9s 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 \u00fanico del destinatario"
          },
          "name": {
            "type": "string",
            "description": "Nombre completo combinado"
          },
          "email": {
            "type": "string",
            "format": "email",
            "description": "Direcci\u00f3n de correo electr\u00f3nico 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\u00f3n, 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\u00e1ndo este destinatario complet\u00f3 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 \u00fanico de la solicitud de firma"
          },
          "name": {
            "type": "string",
            "description": "Nombre de la solicitud de firma",
            "maxLength": 255
          },
          "description": {
            "type": "string",
            "nullable": true,
            "description": "Descripci\u00f3n de la solicitud de firma"
          },
          "status": {
            "type": "string",
            "enum": [
              "draft"
            ],
            "description": "El status siempre es 'draft' para solicitudes de firma reci\u00e9n creadas"
          },
          "document_url": {
            "type": "string",
            "format": "uri",
            "description": "URL prefirmada al documento PDF"
          },
          "page_count": {
            "type": "integer",
            "minimum": 1,
            "description": "N\u00famero de p\u00e1ginas 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\u00edas)"
          },
          "template_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID de la plantilla si se cre\u00f3 a partir de una plantilla"
          },
          "settings": {
            "$ref": "#/components/schemas/SigningRequestSettings"
          },
          "created_date": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de creaci\u00f3n"
          },
          "updated_date": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de la \u00faltima actualizaci\u00f3n"
          },
          "sent_date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Cu\u00e1ndo se envi\u00f3 la solicitud de firma"
          },
          "finished_date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Cu\u00e1ndo se completaron todas las firmas"
          },
          "cancelled_date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Cu\u00e1ndo se cancel\u00f3 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\u00f3n planos",
            "items": {
              "$ref": "#/components/schemas/SigningRequestCreateField"
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Advertencias opcionales de validaci\u00f3n de formato de correo electr\u00f3nico. Solo est\u00e1n presentes cuando los correos electr\u00f3nicos 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 \u00fanico 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\u00e1ticamente a partir de first_name + last_name)"
          },
          "email": {
            "type": "string",
            "format": "email",
            "description": "Direcci\u00f3n de correo electr\u00f3nico 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\u00f3n, CC recibe una copia cuando se completa."
          },
          "order": {
            "type": "integer",
            "minimum": 1,
            "description": "Orden de firma"
          },
          "phone_number": {
            "type": "string",
            "nullable": true,
            "description": "N\u00famero de tel\u00e9fono del destinatario"
          },
          "street_address": {
            "type": "string",
            "nullable": true,
            "description": "Direcci\u00f3n 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\u00f3digo postal"
          },
          "country": {
            "type": "string",
            "nullable": true,
            "description": "Pa\u00eds"
          },
          "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\u00e1ndo este destinatario complet\u00f3 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\u00f3n plana, estilo base de datos)",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identificador \u00fanico 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\u00famero de p\u00e1gina (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\u00e1tico 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\u00f3n del campo personalizado (por ejemplo, 'artist_name'). Solo est\u00e1 presente para campos vinculados a una definici\u00f3n 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\u00f3n 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 \u00fanico de la Solicitud de Firma"
          },
          "name": {
            "type": "string",
            "description": "Nombre de la Solicitud de Firma"
          },
          "template_description": {
            "type": "string",
            "nullable": true,
            "description": "Descripci\u00f3n 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\u00e1ginas 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\u00e1ndo expira la Solicitud de Firma. Se calcula a partir de sent_on + expiration_hours. Es null si a\u00fan no se envi\u00f3 o si no se estableci\u00f3 expiration_hours."
          },
          "credit_cost": {
            "type": "integer",
            "description": "Cr\u00e9ditos 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\u00f3n del estado de generaci\u00f3n 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\u00e1ndo se gener\u00f3 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\u00e9s 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\u00e9s 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\u00e9s 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\u00f3n 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\u00fan su order. Cuando es false, todos los Firmantes reciben el documento al mismo tiempo.",
            "default": true
          },
          "hand_drawn_only": {
            "type": "boolean",
            "description": "Cuando est\u00e1 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\u00f3n de la Solicitud de Firma a los Firmantes",
            "default": true
          },
          "send_finish_email": {
            "type": "boolean",
            "description": "Si se debe enviar un correo de finalizaci\u00f3n cuando todos los Firmantes terminan",
            "default": true
          },
          "send_expiration_email": {
            "type": "boolean",
            "description": "Si se debe enviar un correo de notificaci\u00f3n de expiraci\u00f3n cuando la solicitud expira",
            "default": true
          },
          "send_cancellation_email": {
            "type": "boolean",
            "description": "Si se debe enviar un correo de notificaci\u00f3n de cancelaci\u00f3n 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\u00f3digo de un solo uso antes de acceder al documento. null = hereda la configuraci\u00f3n del Espacio de Trabajo/empresa.",
            "default": null
          },
          "disable_guided_navigation": {
            "type": "boolean",
            "nullable": true,
            "description": "Desactiva el desplazamiento autom\u00e1tico al siguiente campo requerido durante la firma. Hereda del Espacio de Trabajo o de la empresa si no est\u00e1 configurado."
          },
          "allow_presigning_download": {
            "type": "boolean",
            "nullable": true,
            "description": "Permite a los Firmantes descargar el documento original antes de firmar. Hereda de la configuraci\u00f3n del Espacio de Trabajo o de la empresa cuando es null."
          },
          "show_qr_code": {
            "type": "boolean",
            "nullable": true,
            "description": "Muestra un c\u00f3digo QR en la p\u00e1gina de firma que permite a los Firmantes continuar desde su tel\u00e9fono. Hereda de la configuraci\u00f3n 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\u00e1 configurado, un di\u00e1logo de confirmaci\u00f3n permite a los Firmantes editar los campos especificados."
          },
          "notify_identity_change_email": {
            "type": "boolean",
            "default": false,
            "description": "Env\u00eda una notificaci\u00f3n por correo cuando un Firmante cambia su identidad."
          }
        }
      },
      "TemplateSettings": {
        "type": "object",
        "description": "Configuraci\u00f3n 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\u00e1 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\u00f3n de la Solicitud de Firma a los Firmantes",
            "default": true
          },
          "send_finish_email": {
            "type": "boolean",
            "description": "Si se debe enviar un correo de finalizaci\u00f3n cuando todos los Firmantes terminan",
            "default": true
          },
          "send_expiration_email": {
            "type": "boolean",
            "description": "Si se debe enviar un correo de notificaci\u00f3n de expiraci\u00f3n cuando la solicitud expira",
            "default": true
          },
          "send_cancellation_email": {
            "type": "boolean",
            "description": "Indica si se debe enviar un correo de notificaci\u00f3n de cancelaci\u00f3n cuando se cancela la solicitud",
            "default": true
          },
          "require_otp_verification": {
            "type": "boolean",
            "nullable": true,
            "description": "Indica si los firmantes deben verificar su correo electr\u00f3nico con un c\u00f3digo de un solo uso antes de acceder al documento. null = heredar de la configuraci\u00f3n del espacio de trabajo/empresa.",
            "default": null
          },
          "disable_guided_navigation": {
            "type": "boolean",
            "nullable": true,
            "description": "Desactiva el desplazamiento autom\u00e1tico al siguiente campo requerido durante la firma. Se hereda del espacio de trabajo o la empresa si no est\u00e1 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\u00f3n del espacio de trabajo o la empresa cuando es null."
          },
          "show_qr_code": {
            "type": "boolean",
            "nullable": true,
            "description": "Muestra un c\u00f3digo QR en la p\u00e1gina de firma que permite a los firmantes continuar desde su tel\u00e9fono. Se hereda de la configuraci\u00f3n del espacio de trabajo o la empresa cuando es null."
          }
        }
      },
      "LegacyDocumentSettings": {
        "type": "object",
        "description": "Configuraci\u00f3n 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\u00e1 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\u00f3n de solicitud de firma a los firmantes",
            "default": true
          },
          "send_finish_email": {
            "type": "boolean",
            "description": "Indica si se debe enviar un correo de finalizaci\u00f3n cuando todos los firmantes terminan",
            "default": true
          },
          "send_expiration_email": {
            "type": "boolean",
            "description": "Indica si se debe enviar un correo de notificaci\u00f3n de expiraci\u00f3n cuando la solicitud expira",
            "default": true
          },
          "send_cancellation_email": {
            "type": "boolean",
            "description": "Indica si se debe enviar un correo de notificaci\u00f3n de cancelaci\u00f3n cuando se cancela la solicitud",
            "default": true
          },
          "disable_guided_navigation": {
            "type": "boolean",
            "nullable": true,
            "description": "Desactiva el desplazamiento autom\u00e1tico al siguiente campo requerido durante la firma. Se hereda del espacio de trabajo o la empresa si no est\u00e1 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\u00f3n 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\u00f3n y mapeo. **Campo Name**: Se construye autom\u00e1ticamente a partir de first_name y last_name ('First Last' si ambos est\u00e1n presentes, de lo contrario 'First'). Los valores de name ingresados manualmente se sobrescriben. **Asignaci\u00f3n de order**: TODOS los destinatarios DEBEN tener un valor de order expl\u00edcito. Order determina la secuencia de firma, que siempre se aplica. Los destinatarios deben firmar en orden, firmando primero los n\u00fameros m\u00e1s bajos. **Campos personalizados**: Admite tanto la estructura plana (por ejemplo, company_name en la ra\u00edz) 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\u00f3n del usuario (name, email, phone, etc.); order y designation se heredan de la plantilla. **IDs temporales**: Para la creaci\u00f3n 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 \u00fanico. Para actualizaciones: use el UUID existente. Para la creaci\u00f3n 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\u00f3n. Los IDs temporales se resuelven autom\u00e1ticamente a UUIDs reales en la respuesta."
          },
          "_temp_id": {
            "type": "string",
            "description": "Identificador temporal para destinatarios nuevos en solicitudes PUT (actualizaci\u00f3n integral) (por ejemplo, 'temp_1'). \u00daselo al crear destinatarios nuevos junto con destinatarios existentes en actualizaciones integrales. Debe comenzar con 'temp_' y ser \u00fanico dentro de la solicitud. No se usa para solicitudes POST (creaci\u00f3n); 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\u00e1n al usuario de plantilla correspondiente. Si no se proporciona, se recurre a la coincidencia por orden. Solo se puede actualizar la informaci\u00f3n del usuario (nombre, email, tel\u00e9fono, direcci\u00f3n, cargo, empresa) - el orden y la designaci\u00f3n 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\u00f3n 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\u00f3n, CC recibe una copia al completarse."
          },
          "order": {
            "type": "integer",
            "minimum": 1,
            "description": "N\u00famero de secuencia de firma. Los destinatarios deben firmar en orden, firmando primero los n\u00fameros m\u00e1s bajos. Este campo es obligatorio para todos los destinatarios."
          },
          "phone_number": {
            "type": "string",
            "maxLength": 50,
            "nullable": true,
            "description": "N\u00famero de tel\u00e9fono del destinatario"
          },
          "street_address": {
            "type": "string",
            "maxLength": 255,
            "nullable": true,
            "description": "Direcci\u00f3n 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\u00f3digo postal"
          },
          "country": {
            "type": "string",
            "maxLength": 100,
            "nullable": true,
            "description": "Pa\u00eds"
          },
          "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\u00f3n 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\u00e1tico, o prefilled_data para autocompletar a partir de los atributos del destinatario. **Fusi\u00f3n 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\u00f3n parcial). Los campos sin coincidencia se ignoran.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identificador \u00fanico (incl\u00fayelo para actualizaciones, om\u00edtelo 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\u00f3n basada en plantilla). \u00dasalo para identificar qu\u00e9 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\u00edmites de la p\u00e1gina: 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\u00famero de p\u00e1gina donde se ubica el campo (indexado desde 1). No debe exceder el total de p\u00e1ginas 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\u00f3n o actualizaciones basadas en plantilla, o un ID temporal (por ejemplo, 'temp_1') para creaci\u00f3n 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\u00e9n se usa como alternativa para la coincidencia de campos en creaci\u00f3n basada en plantilla cuando no se proporciona template_field_id."
          },
          "variable_defined_name": {
            "type": "string",
            "maxLength": 100,
            "nullable": true,
            "description": "Nombre de definici\u00f3n de campo personalizado, legible por humanos. Puede usarse como alternativa a variable_name para apuntar a campos en creaci\u00f3n 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\u00f3n o bot\u00f3n de opci\u00f3n entre s\u00ed. Los campos que comparten el mismo multi_group_id se comportan como un grupo mutuamente excluyente (como botones de opci\u00f3n) - seleccionar uno deselecciona autom\u00e1ticamente los dem\u00e1s del grupo. Usa el mismo UUID en varios campos para crear un grupo donde solo se pueda seleccionar una opci\u00f3n 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 }. Los campos con texto (text, textarea, email, name, phone, company, title, number, dropdown, url, date) aceptan adem\u00e1s una propiedad opcional fontSize (entero en px, 8-48, con l\u00edmites) \u2014 consulta TextFormatRules."
          },
          "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. \u00datil para mostrar los t\u00e9rminos del contrato, informaci\u00f3n del destinatario u otros datos fijos."
          },
          "read_only_value": {
            "type": "string",
            "nullable": true,
            "description": "Valor est\u00e1tico 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\u00e9n 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\u00e1 configurado. Ejemplo: config\u00faralo como 'email' para mostrar la direcci\u00f3n de correo electr\u00f3nico del destinatario."
          },
          "required_conditions": {
            "$ref": "#/components/schemas/ConditionSet",
            "nullable": true,
            "description": "Reglas condicionales para cu\u00e1ndo este campo es obligatorio. Cuando se configura, tiene prioridad sobre el indicador est\u00e1tico 'required'. El campo solo es obligatorio cuando las condiciones se eval\u00faan como verdaderas seg\u00fan los valores de otros campos."
          },
          "visibility_conditions": {
            "$ref": "#/components/schemas/ConditionSet",
            "nullable": true,
            "description": "Reglas condicionales para cu\u00e1ndo este campo es visible. Cuando se configura, el campo permanece oculto a menos que las condiciones se eval\u00faen 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'). \u00datil para resaltar campos que necesitan atenci\u00f3n.",
            "example": "#FFFDE7"
          }
        }
      },
      "AnchorTag": {
        "type": "object",
        "required": [
          "anchor_string",
          "type",
          "recipient_id"
        ],
        "description": "Definici\u00f3n de etiqueta de anclaje para la colocaci\u00f3n autom\u00e1tica de campos. Las etiquetas de anclaje son marcadores de texto incrustados en un documento PDF (por ejemplo, '{{SIGN_HERE}}') que se localizan autom\u00e1ticamente y se convierten en campos posicionados. El texto del anclaje se elimina del PDF despu\u00e9s 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\u00f3n 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\u00f3n basada en documentos, o un n\u00famero entero de orden para la basada en plantillas.",
            "example": "temp_1"
          },
          "x_offset": {
            "type": "number",
            "description": "Desplazamiento horizontal desde la posici\u00f3n del anclaje. Las unidades se determinan mediante offset_units (predeterminado: porcentaje del ancho de p\u00e1gina).",
            "default": 0
          },
          "y_offset": {
            "type": "number",
            "description": "Desplazamiento vertical desde la posici\u00f3n del anclaje. Las unidades se determinan mediante offset_units (predeterminado: porcentaje del alto de p\u00e1gina).",
            "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\u00e1gina, 'pixels' = puntos PDF (72 DPI)."
          },
          "width": {
            "type": "number",
            "minimum": 0,
            "exclusiveMinimum": true,
            "description": "Ancho del campo como porcentaje del ancho de p\u00e1gina. Los valores predeterminados var\u00edan seg\u00fan 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\u00e1gina. Los valores predeterminados var\u00edan seg\u00fan 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\u00fasculas y min\u00fasculas"
          },
          "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\u00f3n."
          },
          "occurrence": {
            "type": "integer",
            "minimum": 0,
            "maximum": 1000,
            "default": 0,
            "description": "Qu\u00e9 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\u00e1ngulo blanco sobre \u00e9l"
          },
          "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\u00e1tico 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\u00f3n de campo personalizado. Se puede usar como alternativa a variable_name para apuntar a campos en la creaci\u00f3n 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"
          },
          "font_size": {
            "type": "integer",
            "minimum": 8,
            "maximum": 48,
            "description": "Tama\u00f1o de fuente inicial/m\u00e1ximo opcional en p\u00edxeles para tipos de campo con texto, almacenado en el campo resuelto como format_rules.fontSize (consulta TextFormatRules). El texto se reduce autom\u00e1ticamente para ajustarse al recuadro del campo. Om\u00edtelo para el dimensionado autom\u00e1tico. Los valores fuera de 8-48 se limitan a ese rango; los valores no num\u00e9ricos se ignoran.",
            "example": 12
          },
          "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\u00f3n/radio"
          }
        }
      },
      "ConditionSet": {
        "type": "object",
        "required": [
          "logic",
          "groups"
        ],
        "description": "Un conjunto de grupos de condiciones con l\u00f3gica 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\u00f3n puede coincidir (OR).",
        "properties": {
          "logic": {
            "type": "string",
            "enum": [
              "and",
              "or"
            ],
            "description": "Operador l\u00f3gico 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\u00f3n que eval\u00faa 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\u00f3n. 'is_filled'/'is_empty' no requieren un valor. Operadores de texto: equals, not_equals, contains, not_contains. Operadores num\u00e9ricos/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 \u00fanico (incl\u00fayelo para actualizaciones, om\u00edtelo para recordatorios nuevos)"
          },
          "hours": {
            "type": "integer",
            "minimum": 1,
            "description": "Horas antes de la expiraci\u00f3n 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\u00edfico (obligatorio si all_users es false). Usa un UUID real para destinatarios existentes o un ID temporal (por ejemplo, 'temp_1') para creaci\u00f3n 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\u00f3n 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 \u00fanico 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\u00f3n 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\u00f3n, 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\u00e1ndo este destinatario complet\u00f3 todas las acciones"
          },
          "declined_on": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Marca de tiempo de cu\u00e1ndo este destinatario rechaz\u00f3 firmar"
          },
          "decline_reason": {
            "type": "string",
            "nullable": true,
            "description": "Motivo proporcionado por el destinatario para el rechazo"
          },
          "phone_number": {
            "type": "string",
            "nullable": true,
            "description": "N\u00famero de tel\u00e9fono del destinatario"
          },
          "street_address": {
            "type": "string",
            "nullable": true,
            "description": "Direcci\u00f3n 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\u00f3digo postal del destinatario"
          },
          "country": {
            "type": "string",
            "nullable": true,
            "description": "Pa\u00eds 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\u00edo (seg\u00fan 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\u00e1n vac\u00edos 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\u00f3n del campo personalizado (por ejemplo, 'artist_name'). Solo est\u00e1 presente para campos vinculados a una definici\u00f3n 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\u00edo"
          },
          "ready_to_send": {
            "type": "boolean",
            "description": "Indica si este destinatario tiene todos los datos requeridos completados para el env\u00edo"
          }
        },
        "required": [
          "id",
          "first_name",
          "email",
          "designation",
          "order"
        ]
      },
      "SigningRequestField": {
        "type": "object",
        "description": "Campo asociado a una solicitud de firma, que contiene informaci\u00f3n de posici\u00f3n, tipo y valor",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identificador \u00fanico 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\u00f3n y dimensiones del campo en el documento. Todos los valores son porcentajes (0-100).",
            "properties": {
              "x": {
                "type": "number",
                "nullable": true,
                "description": "Posici\u00f3n X (porcentaje, 0-100). Alias limpio de x_postion."
              },
              "y": {
                "type": "number",
                "nullable": true,
                "description": "Posici\u00f3n 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\u00e1metro 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\u00f3n X (nota: el nombre de la columna tiene un error tipogr\u00e1fico)."
          },
          "y_position": {
            "type": "number",
            "nullable": true,
            "description": "Obsoleto: usa 'position.y' en su lugar. Posici\u00f3n 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\u00e1fico)."
          },
          "page_number": {
            "type": "integer",
            "nullable": true,
            "description": "N\u00famero de p\u00e1gina donde se encuentra el campo (indexado desde 1)"
          },
          "tl_position": {
            "type": "number",
            "nullable": true,
            "description": "Posici\u00f3n de la esquina superior izquierda"
          },
          "tr_position": {
            "type": "number",
            "nullable": true,
            "description": "Posici\u00f3n de la esquina superior derecha"
          },
          "bl_position": {
            "type": "number",
            "nullable": true,
            "description": "Posici\u00f3n de la esquina inferior izquierda"
          },
          "br_position": {
            "type": "number",
            "nullable": true,
            "description": "Posici\u00f3n 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\u00f3n del campo personalizado (por ejemplo, 'artist_name'). Solo est\u00e1 presente en campos vinculados a una definici\u00f3n 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\u00f3n 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\u00f3n o bot\u00f3n de opci\u00f3n entre s\u00ed. Los campos que comparten el mismo multi_group_id se comportan como un grupo mutuamente excluyente (como botones de opci\u00f3n); seleccionar uno deselecciona autom\u00e1ticamente los dem\u00e1s del grupo. Usa el mismo UUID en varios campos para crear un grupo donde solo se pueda seleccionar una opci\u00f3n 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\u00e1tico 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\u00f1o de fuente calculado para el campo"
          },
          "deleted": {
            "type": "integer",
            "enum": [
              0,
              1
            ],
            "description": "Obsoleto: campo interno, se eliminar\u00e1 en v2. Indicador de eliminaci\u00f3n l\u00f3gica (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\u00f3 correctamente"
          },
          "message": {
            "type": "string",
            "description": "Mensaje de \u00e9xito"
          },
          "sentTo": {
            "type": "string",
            "format": "email",
            "description": "Direcci\u00f3n de correo electr\u00f3nico a la que se envi\u00f3 la Solicitud de Firma"
          },
          "sentAt": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de cuando se envi\u00f3 la solicitud"
          }
        }
      },
      "Webhook": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identificador \u00fanico del Webhook"
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "URL del Webhook"
          },
          "description": {
            "type": "string",
            "nullable": true,
            "description": "Descripci\u00f3n del Webhook"
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Eventos que activan este Webhook"
          },
          "enabled": {
            "type": "boolean",
            "description": "Si el Webhook est\u00e1 habilitado"
          },
          "consecutive_failures": {
            "type": "integer",
            "description": "N\u00famero 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\u00f3 autom\u00e1ticamente debido a fallos"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de creaci\u00f3n del Webhook"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de la \u00faltima actualizaci\u00f3n 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\u00e1ticamente a PDF. El n\u00famero de p\u00e1ginas se extraer\u00e1 autom\u00e1ticamente."
              },
              "name": {
                "type": "string",
                "maxLength": 255,
                "description": "Nombre para la Solicitud de Firma"
              },
              "description": {
                "type": "string",
                "description": "Descripci\u00f3n 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\u00edas)"
              },
              "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\u00f3n autom\u00e1tica 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\u00e9s del procesamiento. Los campos creados a partir de etiquetas de anclaje se a\u00f1aden junto con cualquier campo especificado manualmente. Solo est\u00e1 disponible para la creaci\u00f3n 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\u00f3n de la Solicitud de Firma"
              },
              "language": {
                "type": "string",
                "nullable": true,
                "enum": [
                  "en",
                  "es",
                  "it",
                  "pt",
                  "fr",
                  "de",
                  "el",
                  "ru",
                  "pl",
                  "cs",
                  "sv",
                  "nl",
                  "ro",
                  "nb"
                ],
                "description": "Idioma opcional de los correos para esta solicitud de firma. Cuando se establece, todos los correos dirigidos al firmante (y el formato de fecha) lo utilizan. Om\u00edtelo o usa null para volver al idioma predeterminado del espacio de trabajo y luego de la empresa (sin cambios de comportamiento)."
              }
            }
          },
          {
            "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\u00e1n 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\u00f3n personalizada (usa la descripci\u00f3n de la Plantilla de forma predeterminada si no se proporciona)"
              },
              "expiration_hours": {
                "type": "integer",
                "minimum": 1,
                "description": "Sobrescribir las horas de expiraci\u00f3n 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\u00f3n del usuario (first_name, last_name, email, phone_number, campos de direcci\u00f3n, title, company); order y designation siempre se heredan de la Plantilla. Los destinatarios no proporcionados usar\u00e1n 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\u00f3n de la plantilla"
              },
              "language": {
                "type": "string",
                "nullable": true,
                "enum": [
                  "en",
                  "es",
                  "it",
                  "pt",
                  "fr",
                  "de",
                  "el",
                  "ru",
                  "pl",
                  "cs",
                  "sv",
                  "nl",
                  "ro",
                  "nb"
                ],
                "description": "Idioma opcional de los correos para esta solicitud de firma. Cuando se establece, todos los correos dirigidos al firmante (y el formato de fecha) lo utilizan. Om\u00edtelo o usa null para volver al idioma predeterminado del espacio de trabajo y luego de la empresa (sin cambios de comportamiento)."
              }
            },
            "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\u00ed 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\u00f3mo 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\u00e1ticamente las referencias de la condici\u00f3n; si es false (predeterminado), la solicitud se rechazar\u00e1 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"
          },
          "language": {
            "type": "string",
            "nullable": true,
            "enum": [
              "en",
              "es",
              "it",
              "pt",
              "fr",
              "de",
              "el",
              "ru",
              "pl",
              "cs",
              "sv",
              "nl",
              "ro",
              "nb"
            ],
            "description": "Idioma opcional de los correos para esta solicitud de firma. Cuando se establece, todos los correos dirigidos al firmante (y el formato de fecha) lo utilizan. Om\u00edtelo o usa null para volver al idioma predeterminado del espacio de trabajo y luego de la empresa (sin cambios de comportamiento)."
          }
        }
      },
      "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\u00e1 el JWT"
          }
        }
      },
      "GenerateJWTResponse": {
        "type": "object",
        "properties": {
          "token": {
            "type": "string",
            "description": "El token JWT generado"
          },
          "jwt_record_id": {
            "type": "string",
            "format": "uuid",
            "description": "Identificador \u00fanico de este registro JWT"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de expiraci\u00f3n del JWT (30 d\u00edas desde su creaci\u00f3n)"
          }
        },
        "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\u00f3n"
          },
          "jwt_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID del JWT revocado"
          },
          "revoked": {
            "type": "boolean",
            "description": "Indica si el JWT se revoc\u00f3 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\u00e1 el JWT"
          }
        }
      },
      "GenerateSigningRequestJWTResponse": {
        "type": "object",
        "properties": {
          "jwt": {
            "type": "string",
            "description": "El token JWT generado"
          },
          "jwt_id": {
            "type": "string",
            "format": "uuid",
            "description": "Identificador \u00fanico de este JWT"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de expiraci\u00f3n del JWT (7 d\u00edas desde su creaci\u00f3n)"
          },
          "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\u00e1ndo se cre\u00f3 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\u00f3n"
          },
          "jwt_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID del JWT revocado"
          },
          "revoked": {
            "type": "boolean",
            "description": "Indica si el JWT se revoc\u00f3 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\u00f3n 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\u00e1gina/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\u00e1 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\u00f3digo QR en la p\u00e1gina de firma que permite a los firmantes continuar desde su tel\u00e9fono. 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\u00f3nico 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\u00f3nico",
            "enum": [
              "en",
              "es",
              "it",
              "pt",
              "fr",
              "de",
              "el",
              "ru",
              "pl",
              "cs",
              "sv",
              "nl",
              "ro",
              "nb"
            ],
            "default": "en"
          },
          "signing_request_email_header": {
            "type": "string",
            "description": "Texto de encabezado de correo electr\u00f3nico personalizado"
          },
          "signing_request_email_body": {
            "type": "string",
            "description": "Cuerpo de correo electr\u00f3nico HTML personalizado"
          },
          "show_credit_cost_in_editor": {
            "type": "boolean",
            "description": "Indica si se debe mostrar el costo en cr\u00e9ditos 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\u00f3nico mediante OTP antes de acceder a los documentos. null = heredar de la configuraci\u00f3n 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\u00e9rminos antes de firmar. null hereda la configuraci\u00f3n a nivel de empresa."
          },
          "disable_guided_navigation": {
            "type": "boolean",
            "nullable": true,
            "description": "Desactiva el desplazamiento autom\u00e1tico hacia el siguiente campo requerido durante la firma. Hereda del espacio de trabajo o de la empresa si no est\u00e1 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\u00f3n 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\u00f3n 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\u00f3n a nivel de empresa."
          },
          "show_qr_code": {
            "type": "boolean",
            "nullable": true,
            "description": "Muestra un c\u00f3digo QR en la p\u00e1gina de firma que permite a los firmantes continuar desde su tel\u00e9fono. null hereda la configuraci\u00f3n a nivel de empresa."
          },
          "color_primary": {
            "type": "string",
            "nullable": true,
            "description": "Anulaci\u00f3n del color primario (hex #rrggbb). Null para heredar de la empresa.",
            "example": "#2563eb"
          },
          "color_primary_fg": {
            "type": "string",
            "nullable": true,
            "description": "Anulaci\u00f3n del color primario de primer plano. Null para heredar.",
            "example": "#ffffff"
          },
          "color_background": {
            "type": "string",
            "nullable": true,
            "description": "Anulaci\u00f3n del color de fondo. Null para heredar.",
            "example": "#0f172a"
          },
          "color_foreground": {
            "type": "string",
            "nullable": true,
            "description": "Anulaci\u00f3n del color de primer plano/texto. Null para heredar.",
            "example": "#ffffff"
          },
          "color_card": {
            "type": "string",
            "nullable": true,
            "description": "Anulaci\u00f3n del color de fondo de las tarjetas. Null para heredar.",
            "example": "#22222a"
          },
          "color_border": {
            "type": "string",
            "nullable": true,
            "description": "Anulaci\u00f3n 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\u00f3n de correo del remitente. Null para heredar de la configuraci\u00f3n 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\u00f3n personalizadas por idioma para la vista de firma. Las claves son c\u00f3digos de idioma (en, de, etc.); los valores son objetos que asignan claves de traducci\u00f3n a texto personalizado. Null para usar los valores predeterminados.",
            "additionalProperties": {
              "type": "object",
              "additionalProperties": {
                "type": "string"
              }
            }
          }
        },
        "required": [
          "workspace_id"
        ]
      },
      "WorkspaceCustomField": {
        "type": "object",
        "description": "Una definici\u00f3n de campo personalizado para un Espacio de Trabajo",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identificador \u00fanico"
          },
          "field_name": {
            "type": "string",
            "description": "Nombre de campo legible por m\u00e1quina (generado autom\u00e1ticamente a partir de la etiqueta)"
          },
          "field_label": {
            "type": "string",
            "description": "Etiqueta de visualizaci\u00f3n 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\u00f3n de campo personalizado para una Plantilla",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identificador \u00fanico"
          },
          "field_name": {
            "type": "string",
            "description": "Nombre de campo legible por m\u00e1quina"
          },
          "field_label": {
            "type": "string",
            "description": "Etiqueta de visualizaci\u00f3n 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\u00f3n de campo personalizado para una Solicitud de Firma",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identificador \u00fanico"
          },
          "field_name": {
            "type": "string",
            "description": "Nombre de campo legible por m\u00e1quina"
          },
          "field_label": {
            "type": "string",
            "description": "Etiqueta de visualizaci\u00f3n legible para humanos"
          },
          "copied_from_template": {
            "type": "boolean",
            "description": "True si este campo se copi\u00f3 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\u00f3n de dominio de correo para enviar correos de Solicitud de Firma",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identificador \u00fanico 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\u00f3n 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\u00edo de correo: 0=registros DNS pendientes de verificaci\u00f3n, 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\u00f3n 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\u00edo de correo. Solo se devuelven despu\u00e9s de la finalizaci\u00f3n del dominio (verification_status=2).",
            "items": {
              "$ref": "#/components/schemas/DomainDnsRecord"
            }
          },
          "date_created": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de creaci\u00f3n del dominio"
          },
          "date_changed": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de la \u00faltima actualizaci\u00f3n del dominio"
          }
        },
        "required": [
          "id",
          "domain",
          "domain_status",
          "verification_status"
        ]
      },
      "DomainDnsRecord": {
        "type": "object",
        "description": "Registro DNS requerido para la verificaci\u00f3n 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\u00f3n de este registro espec\u00edfico"
          }
        }
      },
      "EmailTemplate": {
        "type": "object",
        "description": "Plantilla de correo personalizada para las notificaciones de Solicitud de Firma",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identificador \u00fanico 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\u00ednea 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\u00f3n de la plantilla"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo de la \u00faltima actualizaci\u00f3n 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",
              "cs",
              "sv",
              "nl",
              "ro",
              "nb"
            ]
          },
          "statement_text": {
            "type": "string",
            "description": "Declaraci\u00f3n de consentimiento en HTML depurado"
          },
          "terms_url": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "Enlace externo opcional a los t\u00e9rminos"
          },
          "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\u00f3n 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\u00e1nea parcial del momento en que termin\u00f3 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\u00e1ndo se gener\u00f3 el documento por \u00faltima vez. Para descargas parciales, es cu\u00e1ndo se cre\u00f3 el PDF parcial."
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "description": "Marca de tiempo ISO 8601 de cu\u00e1ndo expira `download_url`. Vuelve a llamar a este endpoint para obtener una URL nueva despu\u00e9s 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\u00f3n 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 \u00e9xito simple con un mensaje",
        "properties": {
          "message": {
            "type": "string",
            "description": "Mensaje de \u00e9xito"
          }
        },
        "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\u00eda",
        "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\u00f3n del evento en formato legible"
                },
                "actor": {
                  "type": "object",
                  "nullable": true,
                  "description": "Qui\u00e9n realiz\u00f3 la acci\u00f3n (nombre/email del firmante o admin/clave API)"
                },
                "ip_address": {
                  "type": "string",
                  "nullable": true,
                  "description": "Direcci\u00f3n IP del firmante (solo eventos de firmante)"
                },
                "details": {
                  "type": "object",
                  "nullable": true,
                  "description": "Metadatos adicionales espec\u00edficos 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\u00f3n",
        "required": [
          "domain",
          "verification_instructions"
        ]
      },
      "DomainDeleteResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "domain_id": {
            "type": "string",
            "format": "uuid"
          }
        },
        "description": "Confirmaci\u00f3n de eliminaci\u00f3n 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\u00f3n 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\u00edo de emails"
          },
          "next_step": {
            "type": "string"
          }
        },
        "description": "Finalizaci\u00f3n 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\u00e1n 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\u00f3n DNS",
        "required": [
          "verified",
          "message",
          "domain"
        ]
      },
      "DomainSetPrimaryResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "domain": {
            "$ref": "#/components/schemas/Domain"
          }
        },
        "description": "Confirmaci\u00f3n de actualizaci\u00f3n 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\u00e1lido junto con el nuevo"
          },
          "warning": {
            "type": "string",
            "description": "Recordatorio para actualizar la verificaci\u00f3n de firma del webhook"
          }
        },
        "description": "Resultado de la rotaci\u00f3n 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\u00e1ndo se cre\u00f3 el secreto del webhook",
            "nullable": true
          },
          "last_rotated_at": {
            "type": "string",
            "format": "date-time",
            "description": "Cu\u00e1ndo se rot\u00f3 por \u00faltima vez el secreto del webhook",
            "nullable": true
          },
          "grace_period_active": {
            "type": "boolean",
            "description": "Indica si el secreto anterior sigue siendo v\u00e1lido junto con el nuevo"
          },
          "grace_period_ends_at": {
            "type": "string",
            "format": "date-time",
            "description": "Cu\u00e1ndo expira el periodo de gracia del secreto anterior",
            "nullable": true
          }
        },
        "description": "Estado del secreto del webhook e informaci\u00f3n de rotaci\u00f3n",
        "required": [
          "created_at"
        ]
      },
      "EmailTemplateDeleteResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "email_type": {
            "type": "string"
          }
        },
        "description": "Confirmaci\u00f3n de eliminaci\u00f3n 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\u00e9rminos del firmante por idioma",
        "required": [
          "terms"
        ]
      },
      "SignerTermsUpdateResponse": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "storedHtml": {
            "type": "string",
            "description": "El HTML saneado que realmente se almacen\u00f3"
          },
          "changed": {
            "type": "boolean",
            "description": "Indica si el saneamiento alter\u00f3 la declaraci\u00f3n enviada"
          }
        },
        "description": "Resultado de la actualizaci\u00f3n de t\u00e9rminos del firmante",
        "required": [
          "ok"
        ]
      },
      "SignerTermsDeleteResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "language": {
            "type": "string"
          }
        },
        "description": "Confirmaci\u00f3n de eliminaci\u00f3n de t\u00e9rminos 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\u00fablica del logo subido"
          }
        },
        "description": "Confirmaci\u00f3n de subida del logo con URL",
        "required": [
          "success",
          "icon_url"
        ]
      },
      "LogoDeleteResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          }
        },
        "description": "Confirmaci\u00f3n de eliminaci\u00f3n del logo",
        "required": [
          "success"
        ]
      },
      "ApiKeyRegenerateResponse": {
        "type": "object",
        "properties": {
          "new_key": {
            "type": "object",
            "description": "La clave API reci\u00e9n generada",
            "properties": {
              "api_key": {
                "type": "string",
                "description": "El valor de la nueva clave API"
              },
              "created_at": {
                "type": "string",
                "format": "date-time",
                "description": "Cu\u00e1ndo se cre\u00f3 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\u00f3n de la clave API",
        "required": [
          "new_key",
          "key_type",
          "workspace_id"
        ]
      },
      "ApiKeyExpireResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "description": "Indica si la operaci\u00f3n tuvo \u00e9xito"
          },
          "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\u00e1ndo estaba originalmente programado que expirara la clave"
                },
                "expired_at": {
                  "type": "string",
                  "format": "date-time",
                  "description": "Cu\u00e1ndo expir\u00f3 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\u00f3n 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\u00f3n 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\u00e9n creada"
          },
          "name": {
            "type": "string",
            "description": "Nombre de la nueva solicitud de firma"
          },
          "description": {
            "type": "string",
            "nullable": true,
            "description": "Descripci\u00f3n 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\u00f3n"
          }
        },
        "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\u00f3n 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\u00famero de p\u00e1ginas del documento"
          },
          "expiration_hours": {
            "type": "integer",
            "description": "Horas hasta la expiraci\u00f3n"
          },
          "settings": {
            "$ref": "#/components/schemas/SigningRequestSettings"
          },
          "created_date": {
            "type": "string",
            "format": "date-time"
          },
          "sent_date": {
            "type": "string",
            "format": "date-time",
            "description": "Cu\u00e1ndo se envi\u00f3 la solicitud"
          },
          "template_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "first_signer": {
            "type": "object",
            "description": "Detalles del primer firmante que recibi\u00f3 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\u00e9ditos de la empresa restantes despu\u00e9s de la deducci\u00f3n"
          }
        },
        "description": "Solicitud de firma creada y enviada",
        "required": [
          "id",
          "name",
          "status"
        ]
      },
      "CreateAndSendValidationError": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          },
          "code": {
            "type": "string",
            "description": "C\u00f3digo de error legible por m\u00e1quina",
            "example": "VALIDATION_ERROR"
          },
          "phase": {
            "type": "string",
            "enum": [
              "create_validation",
              "send_validation"
            ],
            "description": "Qu\u00e9 fase de validaci\u00f3n fall\u00f3"
          },
          "validation_errors": {
            "type": "array",
            "description": "Errores de validaci\u00f3n detallados de la fase de env\u00edo",
            "items": {
              "type": "object",
              "properties": {
                "recipient_index": {
                  "type": "integer",
                  "description": "\u00cdndice 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\u00f3n 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\u00e9ditos 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\u00f3n 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\u00e1ndo expira la URL del documento"
              },
              "document_page_count": {
                "type": "integer",
                "description": "N\u00famero de p\u00e1ginas 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\u00f3n 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\u00f3 a partir de una plantilla"
              },
              "expires_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Timestamp ISO 8601 de cu\u00e1ndo expira la solicitud de firma"
              },
              "created_date": {
                "type": "string",
                "format": "date-time",
                "description": "Timestamp de creaci\u00f3n"
              },
              "sent_date": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Cu\u00e1ndo se envi\u00f3 la solicitud de firma"
              },
              "finished_date": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Cu\u00e1ndo se completaron todas las firmas"
              },
              "cancelled_date": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Cu\u00e1ndo se cancel\u00f3 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\u00f3n",
            "properties": {
              "properties_updated": {
                "type": "boolean",
                "description": "Si se actualiz\u00f3 alguna propiedad"
              },
              "recipients_created": {
                "type": "integer",
                "description": "N\u00famero de destinatarios nuevos creados"
              },
              "recipients_updated": {
                "type": "integer",
                "description": "N\u00famero de destinatarios existentes actualizados"
              },
              "recipients_deleted": {
                "type": "integer",
                "description": "N\u00famero de destinatarios eliminados de forma reversible (soft-delete)"
              },
              "fields_created": {
                "type": "integer",
                "description": "N\u00famero de campos nuevos creados"
              },
              "fields_updated": {
                "type": "integer",
                "description": "N\u00famero de campos existentes actualizados"
              },
              "fields_reassigned": {
                "type": "integer",
                "description": "N\u00famero de campos reasignados a otro destinatario"
              },
              "fields_deleted": {
                "type": "integer",
                "description": "N\u00famero de campos eliminados de forma reversible (soft-delete)"
              },
              "reminders_created": {
                "type": "integer",
                "description": "N\u00famero de recordatorios nuevos creados"
              },
              "reminders_updated": {
                "type": "integer",
                "description": "N\u00famero 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\u00f3n 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\u00f3n 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\u00f3n de eliminaci\u00f3n 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\u00famero de emails de notificaci\u00f3n de cancelaci\u00f3n enviados a los firmantes"
          }
        },
        "description": "Resultado de la cancelaci\u00f3n 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\u00famero de destinatarios cuya notificaci\u00f3n de reenv\u00edo 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\u00edo 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\u00edo",
        "required": [
          "error",
          "code"
        ]
      },
      "TestWebhookResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "description": "Si el webhook de prueba se entreg\u00f3 correctamente"
          },
          "status_code": {
            "type": "integer",
            "description": "C\u00f3digo 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\u00edodo de gracia tras la rotaci\u00f3n del secreto"
              }
            }
          }
        },
        "description": "Resultado de la ejecuci\u00f3n 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\u00f3n 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\u00e9 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"
        ]
      },
      "TemplateCopyResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "ID of the newly created template copy"
          },
          "name": {
            "type": "string",
            "description": "Name of the copied template"
          },
          "workspace_id": {
            "type": "string",
            "format": "uuid",
            "description": "Target workspace the template was copied to"
          },
          "created_date": {
            "type": "string",
            "format": "date-time",
            "description": "Creation timestamp"
          }
        },
        "description": "Template copy response",
        "required": [
          "id",
          "name",
          "workspace_id",
          "created_date"
        ]
      }
    }
  },
  "paths": {
    "/company": {
      "get": {
        "summary": "Obtener informaci\u00f3n de la empresa",
        "description": "Recuperar informaci\u00f3n sobre la empresa autenticada",
        "tags": [
          "Company"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Informaci\u00f3n de la empresa recuperada correctamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "L\u00edmite 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\u00e1ndo se restablece el l\u00edmite 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\u00f3n de la empresa",
        "description": "Actualizar todos los detalles de la empresa. Esta es una operaci\u00f3n 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",
                      "cs",
                      "sv",
                      "nl",
                      "ro",
                      "nb"
                    ],
                    "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\u00f3n 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\u00edmite 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\u00e1ndo se restablece el l\u00edmite de tasa"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Company"
                }
              }
            }
          },
          "400": {
            "description": "Error de validaci\u00f3n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "protectedFields": {
                    "summary": "Se intent\u00f3 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\u00f3n de la empresa",
        "description": "Actualizar campos espec\u00edficos de la empresa. Solo se actualizar\u00e1n 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",
                      "cs",
                      "sv",
                      "nl",
                      "ro",
                      "nb"
                    ],
                    "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\u00f3n 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\u00edmite 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\u00e1ndo se restablece el l\u00edmite de tasa"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Company"
                }
              }
            }
          },
          "400": {
            "description": "Error de validaci\u00f3n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "protectedFields": {
                    "summary": "Se intent\u00f3 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\u00e1lido",
                    "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\u00f3n de la empresa",
        "description": "Recuperar la configuraci\u00f3n de la empresa autenticada",
        "tags": [
          "Company"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Configuraci\u00f3n 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\u00f3n de la empresa",
        "description": "Actualizar la configuraci\u00f3n de la empresa. Solo se actualizar\u00e1n 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\u00f3n predeterminada de la solicitud de firma en horas"
                  },
                  "require_terms_acceptance": {
                    "type": "boolean",
                    "description": "Si los firmantes deben aceptar los t\u00e9rminos 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\u00f3digo QR en la p\u00e1gina de firma que permite a los firmantes continuar en su tel\u00e9fono. 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\u00f3n 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\u00f3nico configurados para la empresa (dominios en el espacio de trabajo protegido/predeterminado). Estos dominios se usan como dominio de env\u00edo 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\u00edmite 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\u00f3nico para la empresa. Esto inicia el proceso de verificaci\u00f3n del dominio. Despu\u00e9s de la creaci\u00f3n, debes:\n1. Agregar un registro TXT a tu DNS con el token de verificaci\u00f3n\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\u00f3nico\n4. Agregar los registros DNS devueltos (SPF, DKIM, etc.)\n5. Llamar a POST /company/domains/{id}/verify-dns para completar la verificaci\u00f3n",
        "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\u00e1lido.",
                    "example": "acme.com"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Dominio creado correctamente. Agrega el registro TXT de verificaci\u00f3n a tu DNS.",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "L\u00edmite 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\u00e1lido 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\u00edfico, incluyendo el estado de verificaci\u00f3n 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 \u00fanico dominio, el env\u00edo 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\u00e9s de agregar el registro TXT de verificaci\u00f3n a tu DNS. La propagaci\u00f3n 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\u00f3n fall\u00f3",
            "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\u00f3n del dominio",
        "description": "Finaliza la configuraci\u00f3n del dominio registr\u00e1ndolo con el proveedor de correo electr\u00f3nico. Esto devuelve los registros DNS (SPF, DKIM, DMARC) que deben agregarse para habilitar el env\u00edo de correo. Solo se puede llamar despu\u00e9s 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\u00e9n configurados correctamente. Llama a esto despu\u00e9s de agregar todos los registros DNS del paso de finalizaci\u00f3n. Una vez verificado, el dominio est\u00e1 listo para enviar correos electr\u00f3nicos.",
        "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\u00f3n 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\u00edo 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\u00famero de p\u00e1gina para la paginaci\u00f3n",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "page_size",
            "in": "query",
            "description": "Cantidad de elementos por p\u00e1gina",
            "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\u00f3n entre may\u00fasculas y min\u00fasculas)"
          },
          {
            "name": "protected",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "0",
                "1",
                "true",
                "false"
              ]
            },
            "description": "Filtrar por estado de protecci\u00f3n"
          },
          {
            "name": "created_after",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Filtrar espacios de trabajo creados despu\u00e9s 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\u00f3n"
          }
        ],
        "responses": {
          "200": {
            "description": "Espacios de trabajo obtenidos correctamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "L\u00edmite 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\u00edmite 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\u00f3n: formato de fecha o par\u00e1metros de ordenaci\u00f3n inv\u00e1lidos",
            "content": {
              "application/json": {
                "examples": {
                  "invalidDate": {
                    "summary": "Formato de fecha inv\u00e1lido",
                    "value": {
                      "error": "Validation failed",
                      "code": "VALIDATION_ERROR",
                      "details": [
                        {
                          "path": [
                            "created_after"
                          ],
                          "message": "created_after must be a valid ISO 8601 date"
                        }
                      ]
                    }
                  },
                  "invalidSort": {
                    "summary": "Par\u00e1metro de ordenaci\u00f3n inv\u00e1lido",
                    "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\u00f3n solo se puede establecer durante la creaci\u00f3n 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\u00edmite 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\u00edmite 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\u00edfico 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\u00edmite 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\u00edmite 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\u00f3n de un espacio de trabajo existente. Esta es una operaci\u00f3n 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\u00edmite 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\u00edmite 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\u00edficos del espacio de trabajo. Solo se puede actualizar el name a trav\u00e9s de la API. El campo protected es de solo lectura y solo puede establecerse durante la creaci\u00f3n 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\u00edmite 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\u00edmite de tasa"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Workspace"
                }
              }
            }
          },
          "400": {
            "description": "Error de validaci\u00f3n",
            "content": {
              "application/json": {
                "examples": {
                  "protectedField": {
                    "summary": "Se intent\u00f3 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\u00f3n 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\u00e9 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\u00edmite 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\u00edmite 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. \u00datil despu\u00e9s 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\u00f3n 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\u00edmite 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\u00edmite 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\u00famero de p\u00e1gina"
          },
          {
            "name": "page_size",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "description": "Elementos por p\u00e1gina"
          },
          {
            "name": "name",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filtrar por nombre de plantilla (coincidencia parcial, sin distinci\u00f3n entre may\u00fasculas y min\u00fasculas)"
          },
          {
            "name": "created_after",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Filtrar plantillas creadas despu\u00e9s 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\u00f3n"
          }
        ],
        "responses": {
          "200": {
            "description": "Plantillas recuperadas exitosamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "L\u00edmite 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\u00e1ticamente el n\u00famero de p\u00e1ginas 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\u00f3n 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\u00e1ticamente a PDF. Tama\u00f1o m\u00e1ximo: 20MB. La API extraer\u00e1 autom\u00e1ticamente el n\u00famero de p\u00e1ginas 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\u00f3n"
                      },
                      "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\u00f3nico con un c\u00f3digo de un solo uso. null = heredar del espacio de trabajo/empresa."
                      },
                      "disable_guided_navigation": {
                        "type": "boolean",
                        "nullable": true,
                        "description": "Deshabilitar el desplazamiento autom\u00e1tico 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\u00f3n del espacio de trabajo o la empresa cuando es null."
                      },
                      "show_qr_code": {
                        "type": "boolean",
                        "nullable": true,
                        "description": "Muestra un c\u00f3digo QR en la p\u00e1gina de firma que permite a los firmantes continuar desde su tel\u00e9fono. Hereda la configuraci\u00f3n 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\u00e9nlo 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\u00edmite 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\u00edfica 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\u00edmite 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\u00faltiples 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\u00f3n 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\u00e1ticamente a PDF. Tama\u00f1o m\u00e1ximo: 20MB"
                      },
                      "expiration_hours": {
                        "type": "integer",
                        "minimum": 1,
                        "description": "Horas hasta la expiraci\u00f3n"
                      },
                      "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\u00f3n del espacio de trabajo o de la empresa cuando es null."
                          },
                          "show_qr_code": {
                            "type": "boolean",
                            "nullable": true,
                            "description": "Muestra un c\u00f3digo QR en la p\u00e1gina de firma que permite a los firmantes continuar desde su tel\u00e9fono. Hereda la configuraci\u00f3n 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\u00fayelo para actualizar un usuario existente, om\u00edtelo 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\u00fayelo para actualizar un campo existente, om\u00edtelo 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\u00e1ticamente. Los campos file permiten a los firmantes subir archivos adjuntos (im\u00e1genes/PDF). Los campos stamp muestran una imagen preconfigurada."
                          },
                          "x": {
                            "type": "number",
                            "description": "Posici\u00f3n X en el documento. Requerido para campos nuevos."
                          },
                          "y": {
                            "type": "number",
                            "description": "Posici\u00f3n 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\u00famero de p\u00e1gina (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\u00f3n del campo. Se puede usar como alternativa a variable_name para apuntar a campos en la creaci\u00f3n 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\u00e1ticamente true para campos url)"
                          },
                          "read_only_value": {
                            "type": "string",
                            "description": "Valor est\u00e1tico 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 \u00e9xito",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "L\u00edmite 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\u00f3n Integral de Plantilla",
        "description": "Actualizaci\u00f3n integral de la plantilla, incluyendo propiedades, usuarios, campos y recordatorios. Admite la eliminaci\u00f3n de usuarios con reasignaci\u00f3n o eliminaci\u00f3n 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\u00f3n 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\u00e1ticamente a PDF. Tama\u00f1o m\u00e1ximo: 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\u00f3n del espacio de trabajo o de la empresa cuando es null."
                          },
                          "show_qr_code": {
                            "type": "boolean",
                            "nullable": true,
                            "description": "Muestra un c\u00f3digo QR en la p\u00e1gina de firma que permite a los firmantes continuar desde su tel\u00e9fono. Hereda la configuraci\u00f3n del espacio de trabajo o de la empresa cuando es null."
                          }
                        }
                      }
                    }
                  },
                  "users": {
                    "type": "array",
                    "description": "Insertar o actualizar usuarios (incluye id para actualizar, om\u00edtelo para crear)",
                    "items": {
                      "type": "object",
                      "required": [
                        "first_name",
                        "email",
                        "designation",
                        "order"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid",
                          "description": "Om\u00edtelo 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\u00e1ticamente las referencias de condici\u00f3n; si es false (predeterminado), la solicitud ser\u00e1 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\u00e9 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\u00f3n."
                        }
                      }
                    }
                  },
                  "fields": {
                    "type": "array",
                    "description": "Crea o actualiza campos (incluye id para actualizar, om\u00edtelo 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\u00f3n X como porcentaje"
                        },
                        "y": {
                          "type": "number",
                          "minimum": 0,
                          "maximum": 100,
                          "description": "Posici\u00f3n 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\u00f3n/botones de opci\u00f3n mutuamente excluyentes"
                        },
                        "variable_name": {
                          "type": "string"
                        },
                        "variable_defined_name": {
                          "type": "string",
                          "maxLength": 100,
                          "nullable": true,
                          "description": "Nombre de definici\u00f3n de campo personalizado legible para humanos. Se puede usar como alternativa a variable_name para apuntar a campos en la creaci\u00f3n 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\u00edtelo 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\u00e9s del env\u00edo 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\u00edmite 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\u00edmite 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\u00edmite 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\u00edfica",
        "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\u00edmite 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\u00edmite 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\u00edfica",
        "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\u00edmite 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\u00edmite 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\u00edfica",
        "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\u00edmite 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\u00edmite 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\u00famero de p\u00e1ginas y dimensiones de p\u00e1gina 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\u00e1ticamente a PDF."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Documento reemplazado correctamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "L\u00edmite 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\u00f3n (n\u00famero de p\u00e1ginas no coincide, dimensiones no coinciden, documento inv\u00e1lido)",
            "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\u00edmite 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\u00famero de p\u00e1gina"
          },
          {
            "name": "page_size",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "description": "Elementos por p\u00e1gina"
          },
          {
            "name": "name",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filtrar por nombre de la solicitud de firma (coincidencia parcial, sin distinci\u00f3n entre may\u00fasculas y min\u00fasculas)"
          },
          {
            "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\u00faltiples valores separados por comas.\n\n**Estados disponibles:**\n- `not_sent`: Solicitud creada pero a\u00fan 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\u00f3 firmar (la solicitud se detiene)\n- `deleted`: Registros eliminados de forma parcial (normalmente ocultos)\n- `expired`: Enviada pero pasado el tiempo de expiraci\u00f3n (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\u00e9s 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\u00f3n 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\u00fasculas/min\u00fasculas)"
          },
          {
            "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\u00f3n"
          }
        ],
        "responses": {
          "200": {
            "description": "Solicitudes de firma obtenidas correctamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "L\u00edmite 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\u00f3n basada en documento, allow_editing_before_sending se establece autom\u00e1ticamente en true. Para la creaci\u00f3n basada en plantilla, las propiedades se heredan de la plantilla y se pueden sobrescribir.\n\n**Patr\u00f3n de ID Temporal**: Para la creaci\u00f3n 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\u00e1ticamente los IDs temporales a UUID reales despu\u00e9s de que se crean los destinatarios. La respuesta contiene solo UUID reales.\n\n**Validaci\u00f3n de ID Temporal**: Los IDs temporales deben comenzar con 'temp_', ser \u00fanicos 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\u00e1lido, IDs duplicados o referencias de destinatario faltantes devuelven un error 400 con mensajes de validaci\u00f3n 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\u00f3n de formato de email (no bloqueantes).",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "L\u00edmite 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\u00e1lida: debes proporcionar 'document' o 'template_id', no ambos. El documento debe ser un PDF v\u00e1lido 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\u00f3mico)",
        "description": "Crea y env\u00eda inmediatamente una solicitud de firma en una \u00fanica operaci\u00f3n at\u00f3mica. 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\u00edo ANTES de crear la solicitud de firma\n- Deducci\u00f3n de cr\u00e9ditos at\u00f3mica: solo cobra si todo tiene \u00e9xito\n- Devuelve status: 'sent' inmediatamente con los detalles del primer firmante\n- M\u00e1s eficiente (ahorra 1 llamada a la API + tiempo de ida y vuelta)\n\n**Validaci\u00f3n:**\n- Todas las validaciones de creaci\u00f3n est\u00e1ndar (document/template, recipients, fields)\n- Validaciones de env\u00edo adicionales:\n  - Todos los firmantes deben tener first_name y un email v\u00e1lido\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\u00e9ditos suficientes (\u22651)\n\n**Atomicidad:**\n- Si alguna validaci\u00f3n falla, no se crea nada\n- El cr\u00e9dito solo se deduce despu\u00e9s de una creaci\u00f3n exitosa y antes del env\u00edo del email\n- Si el env\u00edo del email falla despu\u00e9s de la creaci\u00f3n, la solicitud de firma permanece en estado 'draft' y el cr\u00e9dito NO se deduce\n\n**Patr\u00f3n de ID Temporal:** Para la creaci\u00f3n basada en documento, usa IDs temporales (formato: 'temp_X') para referenciar destinatarios antes de la creaci\u00f3n. La API valida todas las referencias y mapea autom\u00e1ticamente los IDs temporales a UUID reales.\n\n**L\u00edmite 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\u00f3n 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\u00e1ticamente a PDF. Tama\u00f1o m\u00e1ximo: 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\u00edas)",
                    "example": 168
                  },
                  "recipients": {
                    "type": "array",
                    "description": "Array de destinatarios. Al menos uno debe ser un Firmante. Para creaci\u00f3n basada en documento: obligatorio. Para creaci\u00f3n 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\u00f3n 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\u00famero de p\u00e1gina del PDF (indexado desde 1)",
                          "example": 1
                        },
                        "x": {
                          "type": "number",
                          "description": "Coordenada X en la p\u00e1gina",
                          "example": 100
                        },
                        "y": {
                          "type": "number",
                          "description": "Coordenada Y en la p\u00e1gina",
                          "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\u00f3n 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\u00f3n autom\u00e1tica 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\u00e9s del procesamiento. Los campos creados a partir de etiquetas de anclaje se agregan junto a cualquier campo especificado manualmente. Solo disponible para creaci\u00f3n basada en documento (no para creaci\u00f3n 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\u00f3n para enviar el recordatorio",
                          "example": 24
                        }
                      }
                    }
                  },
                  "settings": {
                    "type": "object",
                    "description": "Configuraci\u00f3n de la solicitud de firma",
                    "properties": {
                      "use_signing_order": {
                        "type": "boolean",
                        "default": true,
                        "description": "Aplica el orden de firma seg\u00fan recipient.order. Cuando es false, todos los firmantes reciben el documento simult\u00e1neamente."
                      },
                      "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\u00f3n"
                      },
                      "send_signing_email": {
                        "type": "boolean",
                        "default": true,
                        "description": "Env\u00eda notificaci\u00f3n por correo a los firmantes"
                      },
                      "send_finish_email": {
                        "type": "boolean",
                        "default": true,
                        "description": "Env\u00eda un correo cuando se completan todas las firmas"
                      },
                      "send_expiration_email": {
                        "type": "boolean",
                        "default": true,
                        "description": "Env\u00eda un correo cuando expira la solicitud"
                      },
                      "send_cancellation_email": {
                        "type": "boolean",
                        "default": true,
                        "description": "Env\u00eda 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\u00e1logo de confirmaci\u00f3n que permite a los firmantes editar los campos especificados.",
                        "example": [
                          "name",
                          "company"
                        ]
                      },
                      "notify_identity_change_webhook": {
                        "type": "boolean",
                        "default": false,
                        "description": "Env\u00eda un evento de webhook cuando un firmante cambia su identidad"
                      },
                      "notify_identity_change_email": {
                        "type": "boolean",
                        "default": false,
                        "description": "Env\u00eda notificaci\u00f3n 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"
                  },
                  "language": {
                    "type": "string",
                    "nullable": true,
                    "enum": [
                      "en",
                      "es",
                      "it",
                      "pt",
                      "fr",
                      "de",
                      "el",
                      "ru",
                      "pl",
                      "cs",
                      "sv",
                      "nl",
                      "ro",
                      "nb"
                    ],
                    "description": "Idioma opcional de los correos para esta solicitud de firma. Cuando se establece, todos los correos dirigidos al firmante (y el formato de fecha) lo utilizan. Om\u00edtelo o usa null para volver al idioma predeterminado del espacio de trabajo y luego de la empresa (sin cambios de comportamiento)."
                  }
                },
                "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\u00edmite 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\u00f3n: entrada inv\u00e1lida 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\u00e9ditos 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\u00f3n de correo del destinatario est\u00e1 suprimida (rebot\u00f3 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\u00fan borrador. Los errores del paso de env\u00edo 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\u00edfica 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\u00edmite 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\u00e9s 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\u00f3n"
                      },
                      "document": {
                        "type": "string",
                        "format": "byte",
                        "description": "Reemplaza el documento con un nuevo PDF codificado en base64. El n\u00famero de p\u00e1ginas se extraer\u00e1 autom\u00e1ticamente."
                      },
                      "expiration_hours": {
                        "type": "integer",
                        "minimum": 1,
                        "description": "Nuevas horas de expiraci\u00f3n"
                      },
                      "settings": {
                        "$ref": "#/components/schemas/SigningRequestSettings",
                        "description": "Actualizar configuraci\u00f3n"
                      },
                      "language": {
                        "type": "string",
                        "nullable": true,
                        "enum": [
                          "en",
                          "es",
                          "it",
                          "pt",
                          "fr",
                          "de",
                          "el",
                          "ru",
                          "pl",
                          "cs",
                          "sv",
                          "nl",
                          "ro",
                          "nb"
                        ],
                        "description": "Idioma opcional de los correos para esta solicitud de firma. Cuando se establece, todos los correos dirigidos al firmante (y el formato de fecha) lo utilizan. Om\u00edtelo o usa null para volver al idioma predeterminado del espacio de trabajo y luego de la empresa (sin cambios de comportamiento)."
                      }
                    }
                  },
                  {
                    "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\u00e1ticamente 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\u00fayelo para actualizar un campo existente, om\u00edtelo 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\u00e1ticamente. Los campos file permiten a los firmantes subir archivos adjuntos (im\u00e1genes/PDF). Los campos stamp muestran una imagen preconfigurada."
                          },
                          "position": {
                            "type": "object",
                            "properties": {
                              "x": {
                                "type": "number",
                                "description": "Posici\u00f3n X en el documento"
                              },
                              "y": {
                                "type": "number",
                                "description": "Posici\u00f3n Y en el documento"
                              },
                              "width": {
                                "type": "number",
                                "description": "Ancho del campo"
                              },
                              "height": {
                                "type": "number",
                                "description": "Alto del campo"
                              }
                            },
                            "description": "Objeto de posici\u00f3n. Todas las propiedades son obligatorias para campos nuevos."
                          },
                          "page_number": {
                            "type": "integer",
                            "minimum": 1,
                            "description": "N\u00famero de p\u00e1gina (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\u00f3n de campo personalizado. Se puede usar como alternativa a variable_name para apuntar a campos en la creaci\u00f3n 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\u00f3n para el campo"
                          },
                          "multi_group_id": {
                            "type": "string",
                            "format": "uuid",
                            "description": "ID de grupo para grupos de botones de opci\u00f3n"
                          },
                          "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\u00e1ticamente verdadero para campos url)"
                          },
                          "read_only_value": {
                            "type": "string",
                            "description": "Valor est\u00e1tico 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 \u00fanico",
                  "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\u00f3n 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\u00f3n de propiedades devuelve {id, name, template_description, document_url, expiration_hours}; la actualizaci\u00f3n de destinatario devuelve el objeto de destinatario completo; la actualizaci\u00f3n de campo devuelve el objeto de campo completo. La respuesta puede incluir un campo 'warning' para advertencias de validaci\u00f3n de formato de correo electr\u00f3nico (no bloqueante).",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "L\u00edmite 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\u00f3n 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\u00e9s 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\u00f3n de ID Temporal para Nuevos Destinatarios**: Al agregar nuevos destinatarios en una actualizaci\u00f3n 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\u00f3n: (1) Los IDs temporales deben comenzar con 'temp_'; (2) Cada ID temporal debe ser \u00fanico dentro de la solicitud; (3) Los campos y recordatorios pueden referenciar IDs temporales en su propiedad recipient_id; (4) La API resolver\u00e1 autom\u00e1ticamente los IDs temporales a UUIDs reales despu\u00e9s de la creaci\u00f3n 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\u00edmite 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\u00f3n. Todos los errores de secci\u00f3n 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\u00f3n 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\u00edmite 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\u00edfica",
        "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\u00edmite 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\u00edmite 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\u00edfica 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\u00edmite 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\u00edmite 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\u00edfica",
        "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\u00edmite 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\u00edmite 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\u00eda de una solicitud de firma",
        "description": "Recupera el registro de auditor\u00eda 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\u00f3gicamente.",
        "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\u00eda recuperado correctamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "L\u00edmite 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\u00eda una solicitud de firma a todos los destinatarios por correo electr\u00f3nico. Esto activa el env\u00edo 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\u00edmite 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\u00edmite 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\u00fan no se ha completado. Solo se pueden cancelar solicitudes que ya fueron enviadas y que no est\u00e9n 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\u00f3n opcional"
                  },
                  "notify_signers": {
                    "type": "boolean",
                    "default": true,
                    "description": "Indica si se debe notificar a los firmantes de la cancelaci\u00f3n"
                  }
                }
              },
              "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\u00edmite 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\u00edficos",
        "description": "Reenv\u00eda las notificaciones de la solicitud de firma a uno o m\u00e1s 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\u00e1",
                    "minItems": 1
                  },
                  "custom_message": {
                    "type": "string",
                    "maxLength": 1000,
                    "description": "Mensaje personalizado opcional para incluir en la notificaci\u00f3n de reenv\u00edo"
                  }
                }
              },
              "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\u00edmite 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\u00e1lido, o la solicitud no est\u00e1 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\u00famero de p\u00e1gina"
          },
          {
            "name": "page_size",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "description": "Elementos por p\u00e1gina"
          },
          {
            "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\u00fasculas/min\u00fasculas)"
          },
          {
            "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\u00e9s 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\u00f3n"
          },
          {
            "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\u00edmite 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\u00f3n - formato de fecha o par\u00e1metros de ordenaci\u00f3n no v\u00e1lidos",
            "content": {
              "application/json": {
                "examples": {
                  "invalidDate": {
                    "summary": "Formato de fecha no v\u00e1lido",
                    "value": {
                      "error": "Validation failed",
                      "code": "VALIDATION_ERROR",
                      "details": [
                        {
                          "path": [
                            "created_before"
                          ],
                          "message": "created_before must be a valid ISO 8601 date"
                        }
                      ]
                    }
                  },
                  "invalidSort": {
                    "summary": "Par\u00e1metro de ordenaci\u00f3n no v\u00e1lido",
                    "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\u00edmite 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\u00edfico 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\u00edmite 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\u00edmite 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\u00f3gica 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\u00edmite 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\u00edmite 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\u00edmite 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\u00edmite 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\u00e1lido durante 7 d\u00edas para permitir una migraci\u00f3n 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\u00edmite 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\u00edmite de tasa excedido (1 rotaci\u00f3n 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\u00f3n del secret del webhook",
        "description": "Devuelve informaci\u00f3n sobre el secret de webhook actual, incluyendo el estado de rotaci\u00f3n y la expiraci\u00f3n 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\u00edmite 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\u00f3 configuraci\u00f3n 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\u00f3n de 24 horas. Este es el endpoint est\u00e1ndar para la generaci\u00f3n de JWT.\n\n**Nota**: La funci\u00f3n independiente `generate-embedded-template-token` est\u00e1 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\u00edmite 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\u00edmite 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\u00e1ndar 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\u00edmite 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\u00edmite 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\u00e1lido",
            "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\u00e9s de 7 d\u00edas.",
        "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\u00edmite 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\u00edmite 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\u00f3n 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\u00edmite 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\u00edmite 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\u00e1lido",
            "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\u00edfica 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\u00edfico. Si ya existe una plantilla para este tipo, se actualizar\u00e1. 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\u00ednea de asunto del correo"
                  },
                  "body": {
                    "type": "string",
                    "maxLength": 50000,
                    "description": "Cuerpo del correo (HTML). Use el marcador de posici\u00f3n {{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\u00e1 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\u00edfico. 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\u00ednea 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\u00e1n 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\u00e9rminos del firmante de la empresa",
        "description": "Obtiene todos los t\u00e9rminos del firmante a nivel de empresa. Los t\u00e9rminos del firmante de la empresa sirven como valores predeterminados para los espacios de trabajo que no tienen t\u00e9rminos propios.",
        "tags": [
          "Signer Terms"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "T\u00e9rminos 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\u00e9rminos del firmante de la empresa",
        "description": "Crea o actualiza los t\u00e9rminos del firmante a nivel de empresa para un idioma espec\u00edfico. 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",
                "cs",
                "sv",
                "nl",
                "ro",
                "nb"
              ]
            },
            "description": "C\u00f3digo 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\u00e9rminos"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "T\u00e9rminos 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\u00e9rminos del firmante de la empresa",
        "description": "Elimina los t\u00e9rminos del firmante a nivel de empresa para un idioma espec\u00edfico.",
        "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",
                "cs",
                "sv",
                "nl",
                "ro",
                "nb"
              ]
            },
            "description": "C\u00f3digo de idioma"
          }
        ],
        "responses": {
          "200": {
            "description": "T\u00e9rminos 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\u00e9rminos del firmante del espacio de trabajo",
        "description": "Obtiene todos los t\u00e9rminos 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\u00e9rminos 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\u00e9rminos del firmante del espacio de trabajo",
        "description": "Crea o actualiza los t\u00e9rminos del firmante a nivel de espacio de trabajo para un idioma espec\u00edfico. 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",
                "cs",
                "sv",
                "nl",
                "ro",
                "nb"
              ]
            },
            "description": "C\u00f3digo 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\u00e9rminos"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "T\u00e9rminos 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\u00e9rminos del firmante del espacio de trabajo",
        "description": "Elimina los t\u00e9rminos del firmante a nivel de espacio de trabajo para un idioma espec\u00edfico.",
        "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",
                "cs",
                "sv",
                "nl",
                "ro",
                "nb"
              ]
            },
            "description": "C\u00f3digo de idioma"
          }
        ],
        "responses": {
          "200": {
            "description": "T\u00e9rminos 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\u00edfico. 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",
                "cs",
                "sv",
                "nl",
                "ro",
                "nb"
              ]
            },
            "description": "C\u00f3digo 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\u00edan 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\u00f3n del espacio de trabajo",
        "description": "Obtiene la configuraci\u00f3n 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\u00f3n del espacio de trabajo obtenida exitosamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "L\u00edmite 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\u00f3n del espacio de trabajo",
        "description": "Actualiza la configuraci\u00f3n 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",
                      "cs",
                      "sv",
                      "nl",
                      "ro",
                      "nb"
                    ],
                    "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\u00e9ditos 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\u00e9rminos antes de firmar. null hereda la configuraci\u00f3n a nivel de empresa."
                  },
                  "disable_guided_navigation": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "Desactiva el desplazamiento autom\u00e1tico 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\u00f3n del color de primer plano primario. Null para heredar de la empresa."
                  },
                  "color_background": {
                    "type": "string",
                    "nullable": true,
                    "description": "Anulaci\u00f3n del color de fondo. Null para heredar de la empresa."
                  },
                  "color_foreground": {
                    "type": "string",
                    "nullable": true,
                    "description": "Anulaci\u00f3n del color de primer plano/texto. Null para heredar de la empresa."
                  },
                  "color_card": {
                    "type": "string",
                    "nullable": true,
                    "description": "Anulaci\u00f3n del color de fondo de la tarjeta. Null para heredar de la empresa."
                  },
                  "color_border": {
                    "type": "string",
                    "nullable": true,
                    "description": "Anulaci\u00f3n 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\u00f3n de correo del remitente. Null para heredar de la configuraci\u00f3n 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\u00f3n 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\u00f3n a nivel de empresa."
                  },
                  "show_qr_code": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "Muestra un c\u00f3digo QR en la p\u00e1gina de firma que permite a los firmantes continuar desde su tel\u00e9fono. Hereda de la configuraci\u00f3n del espacio de trabajo o de la empresa cuando es null."
                  },
                  "signing_button_label_overrides": {
                    "type": "object",
                    "nullable": true,
                    "description": "Etiquetas de bot\u00f3n personalizadas por idioma para la vista de firma. Las claves son c\u00f3digos de idioma (en, de, etc.); los valores son objetos que mapean claves de traducci\u00f3n a texto personalizado. Null para usar los valores predeterminados.",
                    "additionalProperties": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Configuraci\u00f3n del espacio de trabajo actualizada correctamente",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "L\u00edmite 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\u00f3nico configurados para un espacio de trabajo espec\u00edfico. 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\u00edmite 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\u00f3nico para un espacio de trabajo espec\u00edfico. Esto inicia el proceso de verificaci\u00f3n del dominio. Despu\u00e9s de la creaci\u00f3n, debes:\n1. Agregar un registro TXT a tu DNS con el token de verificaci\u00f3n\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\u00f3nico\n4. Agregar los registros DNS devueltos (SPF, DKIM, etc.)\n5. Llamar a POST /workspace/{workspace_id}/domains/{id}/verify-dns para completar la verificaci\u00f3n",
        "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\u00e1lido.",
                    "example": "sales.acme.com"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Dominio creado correctamente. Agrega el registro TXT de verificaci\u00f3n a tu DNS.",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "L\u00edmite 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\u00e1lido 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\u00edfico en un espacio de trabajo, incluyendo el estado de verificaci\u00f3n 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 \u00fanico, el env\u00edo 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\u00e9s de agregar el registro TXT de verificaci\u00f3n a tu DNS. La propagaci\u00f3n 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\u00f3n fall\u00f3",
            "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\u00f3n del dominio del espacio de trabajo",
        "description": "Finaliza la configuraci\u00f3n del dominio registr\u00e1ndolo con el proveedor de correo electr\u00f3nico. Esto devuelve los registros DNS (SPF, DKIM, DMARC) que deben agregarse para habilitar el env\u00edo de correo electr\u00f3nico. Solo se puede llamar despu\u00e9s 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\u00e9n configurados correctamente. Llama a esto despu\u00e9s de agregar todos los registros DNS del paso de finalizaci\u00f3n. Una vez verificado, el dominio queda listo para enviar correos electr\u00f3nicos.",
        "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\u00f3n 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\u00edo 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\u00f3n 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\u00e1quina opcional (se genera autom\u00e1ticamente 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\u00e1ximo 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\u00f3n 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\u00f3n 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\u00f3n 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\u00f3n 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\u00f3n 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\u00f3n 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\u00e1lido durante 7 d\u00edas.",
        "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\u00edodo de espera activo \u2014 el secreto se rot\u00f3 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\u00f3n, la fecha de rotaci\u00f3n y el estado del per\u00edodo 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\u00e1 habilitada, devuelve una URL al documento parcialmente firmado generado en el momento en que el \u00faltimo firmante complet\u00f3 su firma.\n\n**Descargas parciales:** Las descargas parciales solo est\u00e1n disponibles cuando la solicitud de firma tiene `allow_partial_download` habilitado en su configuraci\u00f3n. Si el documento a\u00fan no se ha generado parcialmente, se devuelve un `503`; reintenta despu\u00e9s del intervalo indicado en `Retry-After`.\n\n**Expiraci\u00f3n de la URL:** `download_url` es una URL prefirmada que expira. La marca de tiempo de expiraci\u00f3n 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\u00edmite 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\u00fan no ha sido enviada. La descarga solo est\u00e1 disponible despu\u00e9s 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\u00f3n del documento est\u00e1 en progreso. Reintenta despu\u00e9s 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\u00f3n del documento agot\u00f3 el tiempo de espera",
                    "value": {
                      "error": "generation_timeout"
                    }
                  },
                  "stale_at_publication": {
                    "summary": "El documento estaba desactualizado en el momento de la publicaci\u00f3n",
                    "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\u00ed 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\u00f3n del firmante (`include_frame=false` para omitirlo). Cada recuperaci\u00f3n exitosa queda registrada en el registro de auditor\u00eda. L\u00edmite de 60/min. La validez legal recae en el PDF sellado y el certificado de finalizaci\u00f3n, 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) \u2014 el recipient_id de GET /fields",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "include_frame",
            "in": "query",
            "required": false,
            "description": "Superponer el marco de identificaci\u00f3n 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\u00f3n del firmante."
                    },
                    "image": {
                      "type": "string",
                      "description": "PNG como un data URI.",
                      "example": "data:image/png;base64,iVBORw0KGgo..."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Clave API faltante o inv\u00e1lida.",
            "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\u00f3 ninguna marca (SIGNATURE_NOT_AVAILABLE).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "L\u00edmite de solicitudes excedido (60/min para la recuperaci\u00f3n de firmas).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "El renderizado fall\u00f3 (RENDER_FAILED) o la escritura obligatoria del registro de auditor\u00eda de acceso fall\u00f3 (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\u00eda y l\u00edmite 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\u00f3n 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\u00f3n del firmante."
                    },
                    "image": {
                      "type": "string",
                      "description": "PNG como un data URI.",
                      "example": "data:image/png;base64,iVBORw0KGgo..."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Clave API faltante o inv\u00e1lida.",
            "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\u00f3 ninguna marca (SIGNATURE_NOT_AVAILABLE).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "L\u00edmite de solicitudes excedido (60/min para la recuperaci\u00f3n de firmas).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "El renderizado fall\u00f3 (RENDER_FAILED) o la escritura obligatoria del registro de auditor\u00eda de acceso fall\u00f3 (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\u00edfico como un data URI en PNG base64. Los sellos son por campo, as\u00ed que se requiere `field_id` (obtenlo de GET /signing-requests/{id}/fields, filtrando por type=stamp). Mismo encuadre, auditor\u00eda y l\u00edmite 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\u00f3n 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\u00f3n 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\u00e1lida.",
            "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\u00f3 ninguna marca (SIGNATURE_NOT_AVAILABLE).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "L\u00edmite de solicitudes excedido (60/min para la recuperaci\u00f3n de firmas).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "El renderizado fall\u00f3 (RENDER_FAILED) o la escritura obligatoria del registro de auditor\u00eda de acceso fall\u00f3 (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\u00f3 a un campo de archivo. Devuelve una URL de descarga prefirmada de corta duraci\u00f3n (300s), no los bytes. Se requiere `field_id` (de GET /signing-requests/{id}/fields, filtrando por type=file). Cada recuperaci\u00f3n queda registrada en el registro de auditor\u00eda; l\u00edmite 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\u00f3n 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\u00e1lida.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "No encontrado / no est\u00e1 en tu espacio de trabajo (NOT_FOUND) o no se subi\u00f3 ning\u00fan archivo (SIGNATURE_NOT_AVAILABLE).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "L\u00edmite de solicitudes excedido (60/min).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Fall\u00f3 la generaci\u00f3n de la URL firmada (INTERNAL_ERROR) o fall\u00f3 la escritura de auditor\u00eda 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\u00e1ximo 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\u00e1ximo 2MB)"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Logo subido correctamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LogoUploadResponse"
                }
              }
            }
          },
          "400": {
            "description": "Archivo inv\u00e1lido (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\u00e1n 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\u00edfico. Anula el logo de la empresa en los certificados y correos electr\u00f3nicos de este espacio de trabajo. Acepta PNG o JPEG, m\u00e1ximo 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\u00e1ximo 2MB)"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Logo subido correctamente",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LogoUploadResponse"
                }
              }
            }
          },
          "400": {
            "description": "Archivo inv\u00e1lido (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\u00e1n 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\u00edmite de tama\u00f1o de solicitud en base64 en l\u00ednea.",
        "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\u00f1o del archivo en bytes. M\u00e1ximo 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\u00eda los bytes del archivo en bruto con el Content-Type coincidiendo con el content_type solicitado."
                    },
                    "upload_token": {
                      "type": "string",
                      "description": "Token de autenticaci\u00f3n 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\u00f3n (file_size, content_type inv\u00e1lidos, etc.)"
          },
          "401": {
            "description": "Clave API inv\u00e1lida 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);"
          }
        ]
      }
    },
    "/templates/{id}/copy": {
      "post": {
        "summary": "Copy template to another workspace",
        "description": "Deep-copies a template (including fields, recipients, CC, reminders, custom field definitions, and the PDF document) to a target workspace within the same company. Requires a company-level (protected) API key.",
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Template ID to copy"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "workspace_id"
                ],
                "properties": {
                  "workspace_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Target workspace ID to copy the template into"
                  },
                  "name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Name for the copied template (defaults to original name with \" (copy)\" suffix)"
                  }
                }
              },
              "example": {
                "workspace_id": "550e8400-e29b-41d4-a716-446655440000",
                "name": "My Template Copy"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Template copied successfully",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Rate limit: 120 requests per minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateCopyResponse"
                }
              }
            }
          },
          "400": {
            "description": "Missing workspace_id or invalid name",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "403": {
            "description": "Protected API key required, or access denied",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "protected_key_required": {
                    "value": {
                      "error": "This operation requires a protected workspace API key",
                      "code": "PROTECTED_KEY_REQUIRED"
                    }
                  },
                  "access_denied": {
                    "value": {
                      "error": "Template not found or access denied",
                      "code": "ACCESS_DENIED"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Template or target workspace not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          }
        }
      }
    }
  }
}
