{
  "openapi": "3.0.3",
  "info": {
    "title": "API Partenaire Firma",
    "description": "API RESTful pour la signature de documents et la gestion de modèles.\n\n**Authentification** : Tous les endpoints nécessitent une authentification par clé API via l'en-tête `Authorization`. Utilisez votre clé API directement sans préfixe (par exemple, `your-api-key`). Le préfixe Bearer est optionnel mais pas obligatoire.\n\n**Fonctionnalités de sécurité** :\n- Validation des entrées avec des schémas Zod incluant des messages d'erreur détaillés au niveau des champs\n- Jetons JWT signés RSA-256 pour l'accès aux modèles intégrés\n\n**Limitation de débit** : Les limites de débit sont hiérarchisées selon le type d'opération :\n- Opérations de lecture (GET) : 200 requêtes par minute\n- Opérations d'écriture (POST/PUT/PATCH/DELETE) : 120 requêtes par minute\n- Opérations CRUD sur les webhooks : 60 requêtes par minute\n- Test de webhook : 10 requêtes par minute\n- Régénération/expiration de clé API : 1 requête par minute\n- Rotation du secret de webhook : 1 requête par minute\n\nLorsque les limites de débit sont dépassées, l'API renvoie une réponse `429 Too Many Requests` avec les en-têtes suivants :\n- `X-RateLimit-Limit` : Nombre maximal de requêtes par minute pour cet endpoint\n- `X-RateLimit-Remaining` : Requêtes restantes dans la fenêtre actuelle\n- `X-RateLimit-Reset` : Horodatage Unix de la réinitialisation de la limite\n- `Retry-After` : Secondes à attendre avant de pouvoir réessayer\n\n**Gestion des erreurs** : Toutes les erreurs renvoient des réponses JSON structurées avec `error` (message lisible par un humain), `code` (identifiant lisible par une machine) et `details` (erreurs de validation au niveau des champs, le cas échéant).\n\n**Intégration de l'Éditeur de Modèles intégré** : L'Éditeur de Modèles Firma peut être intégré dans votre application à l'aide d'une bibliothèque JavaScript autonome.\n\n```html\n<!-- Charger la bibliothèque de l'Éditeur de Modèles Firma -->\n<script src=\"https://api.firma.dev/functions/v1/embed-proxy/template-editor.js\"></script>\n\n<script>\n// Générer d'abord un jeton JWT via l'API\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  // Initialiser l'éditeur avec le jeton JWT\n  window.FirmaTemplateEditor.init({\n    container: '#firma-editor-container',\n    jwt: data.token,\n    templateId: 'template-id',\n    theme: 'dark',\n    readOnly: false,\n    onSave: (savedData) => {\n      console.log('Template saved:', savedData);\n    },\n    onError: (error) => {\n      console.error('Editor error:', error);\n    },\n    onLoad: (template) => {\n      console.log('Template loaded:', template);\n    }\n  });\n});\n</script>\n```",
    "version": "01.30.00",
    "contact": {
      "name": "API Support",
      "url": "https://firma.com/support"
    }
  },
  "servers": [
    {
      "url": "https://api.firma.dev/functions/v1/signing-request-api",
      "description": "API de Production - Recommandée (Actuelle)"
    },
    {
      "url": "https://api.firma.dev/api/v1",
      "description": "API de Production - Prévue"
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    }
  ],
  "tags": [
    {
      "name": "Company",
      "description": "Informations et paramètres de l'entreprise"
    },
    {
      "name": "Workspaces",
      "description": "Opérations de gestion des Espaces de Travail"
    },
    {
      "name": "Templates",
      "description": "Opérations de gestion des Modèles"
    },
    {
      "name": "Signing Requests",
      "description": "Opérations de Demande de Signature de documents"
    },
    {
      "name": "Custom Fields",
      "description": "Gestion des définitions de champs personnalisés pour les espaces de travail, modèles et demandes de signature"
    },
    {
      "name": "Webhooks",
      "description": "Configuration et gestion des webhooks"
    },
    {
      "name": "JWT Management",
      "description": "Génération et révocation de jetons JWT pour les modèles intégrés"
    },
    {
      "name": "Workspace Settings",
      "description": "Configuration et paramètres de l'espace de travail"
    },
    {
      "name": "Email Domains",
      "description": "Configuration et vérification de domaine e-mail pour l'envoi d'e-mails de demande de signature depuis des domaines personnalisés"
    },
    {
      "name": "Email Templates",
      "description": "Gestion des modèles d'e-mail pour la personnalisation des notifications de demande de signature au niveau de l'espace de travail et de l'entreprise"
    },
    {
      "name": "Signer Terms",
      "description": "Conditions d'utilisation / déclarations de consentement personnalisées pour le signataire, au niveau de l'entreprise avec des surcharges par espace de travail et par langue"
    }
  ],
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "Authorization",
        "description": "Clé API pour l'authentification. Utilisez votre clé API directement sans préfixe (par exemple, 'your-api-key'). Le préfixe Bearer est optionnel mais pas obligatoire."
      }
    },
    "responses": {
      "ValidationError": {
        "description": "Requête Incorrecte - Échec de la validation",
        "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": "Non Autorisé - Clé API invalide ou manquante",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "Unauthorized",
              "message": "Invalid API key"
            }
          }
        }
      },
      "ForbiddenError": {
        "description": "Interdit - Permissions insuffisantes",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "Forbidden",
              "message": "You do not have permission to access this resource"
            }
          }
        }
      },
      "NotFoundError": {
        "description": "Non Trouvé - La ressource n'existe pas",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "Not Found",
              "message": "The requested resource was not found"
            }
          }
        }
      },
      "RateLimitError": {
        "description": "Trop de requêtes - Limite de débit dépassée",
        "headers": {
          "X-RateLimit-Limit": {
            "schema": {
              "type": "integer"
            },
            "description": "Nombre maximum de requêtes par minute"
          },
          "X-RateLimit-Remaining": {
            "schema": {
              "type": "integer"
            },
            "description": "Requêtes restantes"
          },
          "X-RateLimit-Reset": {
            "schema": {
              "type": "integer"
            },
            "description": "Timestamp Unix de la réinitialisation"
          },
          "Retry-After": {
            "schema": {
              "type": "integer"
            },
            "description": "Secondes avant de pouvoir réessayer"
          }
        },
        "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": "Mettre à jour les propriétés",
                "value": {
                  "name": "Updated Contract Name",
                  "expiration_hours": 72
                }
              },
              "update-recipient": {
                "summary": "Mettre à jour un seul destinataire",
                "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": "Ajouter un nouveau destinataire",
                "value": {
                  "recipient": {
                    "first_name": "Jane",
                    "last_name": "Doe",
                    "email": "jane@example.com",
                    "designation": "Signer",
                    "order": 2
                  }
                }
              },
              "add-date-field": {
                "summary": "Ajouter un champ date avec formatage",
                "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": "Ajouter un champ en lecture seule avec valeur statique",
                "description": "Crée un champ texte qui affiche une valeur fixe que le signataire ne peut pas modifier",
                "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": "Ajouter un champ en lecture seule avec les données du destinataire",
                "description": "Crée un champ texte qui se remplit automatiquement avec l'adresse e-mail du destinataire (le signataire ne peut pas le modifier)",
                "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": "Mise à jour complète avec toutes les sections",
                "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": "Mise à jour avec de nouveaux destinataires via des ID temporaires",
                "description": "Mise à jour complète ajoutant de nouveaux destinataires avec des ID temporaires en plus des destinataires existants",
                "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": "Identifiant unique de l'entreprise"
          },
          "name": {
            "type": "string",
            "description": "Nom de l'entreprise",
            "maxLength": 255
          },
          "language": {
            "type": "string",
            "description": "Langue par défaut de l'entreprise",
            "enum": [
              "en",
              "es",
              "it",
              "pt",
              "fr",
              "de",
              "el",
              "ru",
              "pl"
            ],
            "default": "en"
          },
          "account_owner": {
            "type": "string",
            "description": "Nom du propriétaire du compte",
            "maxLength": 255
          },
          "account_owner_email": {
            "type": "string",
            "format": "email",
            "description": "Adresse e-mail du propriétaire du compte"
          },
          "website": {
            "type": "string",
            "format": "uri",
            "description": "URL du site web de l'entreprise",
            "nullable": true
          },
          "icon_url": {
            "type": "string",
            "format": "uri",
            "description": "URL publiquement accessible vers le logo de l'entreprise. Retourne null si aucun logo n'est défini.",
            "nullable": true,
            "example": "https://ielmshcswdhuacyjlpiy.supabase.co/functions/v1/logo/company/3feb35a8-5aaf-4603-8b50-acd807176b38"
          },
          "credits": {
            "type": "integer",
            "description": "Crédits disponibles pour l'entreprise (lecture seule, géré en interne)",
            "minimum": 0,
            "readOnly": true
          },
          "created_date": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp de création du compte entreprise"
          },
          "updated_date": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp de dernière mise à jour du compte entreprise"
          }
        },
        "required": [
          "id",
          "name",
          "account_owner",
          "account_owner_email",
          "created_date"
        ]
      },
      "Workspace": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identifiant unique de l'espace de travail"
          },
          "name": {
            "type": "string",
            "description": "Nom de l'espace de travail",
            "maxLength": 255
          },
          "protected": {
            "type": "boolean",
            "description": "Les espaces de travail protégés ne peuvent pas être supprimés"
          },
          "api_key": {
            "type": "string",
            "description": "Clé API en mode production pour cet espace de travail. Utilisée pour authentifier les requêtes API propres à cet espace de travail.",
            "nullable": true
          },
          "test_api_key": {
            "type": "string",
            "description": "Clé API en mode test pour cet espace de travail. Les requêtes authentifiées avec cette clé ne consomment pas de crédits et produisent des demandes de signature marquées test et filigranées.",
            "nullable": true
          },
          "created_date": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp de création de l'espace de travail"
          },
          "updated_date": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp de dernière mise à jour de l'espace de travail"
          },
          "webhook_enabled": {
            "type": "boolean",
            "description": "Indique si les webhooks au niveau de l'espace de travail sont activés"
          },
          "webhook_secret": {
            "type": "string",
            "description": "Secret de signature webhook pour cet espace de travail",
            "nullable": true
          },
          "webhook_secret_rotated_at": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp de la dernière rotation du secret webhook",
            "nullable": true
          },
          "webhook_secret_created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp de la première création du secret webhook",
            "nullable": true
          },
          "ignore_company_webhooks": {
            "type": "boolean",
            "description": "Si true, les webhooks au niveau de l'entreprise ne se déclenchent pas pour les événements de cet espace de travail"
          },
          "icon_url": {
            "type": "string",
            "format": "uri",
            "description": "URL publiquement accessible vers le logo de l'espace de travail. Retourne le logo propre à l'espace de travail, ou null s'il n'est pas défini (le logo de l'entreprise n'est PAS inclus comme solution de repli dans ce champ).",
            "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": "Identifiant unique du modèle"
          },
          "name": {
            "type": "string",
            "description": "Nom du modèle",
            "maxLength": 255
          },
          "description": {
            "type": "string",
            "description": "Description du modèle",
            "nullable": true
          },
          "document_url": {
            "type": "string",
            "format": "uri",
            "description": "URL pré-signée vers le document PDF. Il s'agit d'une URL signée à durée limitée pour un accès sécurisé, voir document_url_expires_at pour la date d'expiration. Les URL initiales sont valables 7 jours ; les URL rafraîchies sont valables 1 heure. Demandez une nouvelle récupération du modèle pour obtenir une URL fraîche si elle a expiré."
          },
          "document_url_expires_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Timestamp ISO 8601 auquel document_url expirera. Après cette heure, l'URL retournera une erreur d'accès refusé. Récupérez à nouveau le modèle pour recevoir une nouvelle URL signée."
          },
          "page_count": {
            "type": "integer",
            "minimum": 1,
            "description": "Nombre de pages dans le document"
          },
          "expiration_hours": {
            "type": "integer",
            "minimum": 1,
            "default": 168,
            "description": "Nombre d'heures avant l'expiration des demandes de signature créées à partir de ce modèle"
          },
          "credit_cost": {
            "type": "integer",
            "minimum": 1,
            "default": 1,
            "description": "Nombre de crédits consommés lorsqu'une demande de signature est envoyée à partir de ce modèle. La valeur minimale est 1."
          },
          "settings": {
            "$ref": "#/components/schemas/SigningRequestSettings"
          },
          "recipients": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TemplateUser"
            },
            "description": "Destinataires du modèle (inclus dans la récupération d'un seul modèle)"
          },
          "fields": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TemplateField"
            },
            "description": "Champs du modèle (inclus dans la récupération d'un seul modèle)"
          },
          "created_date": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp de création du modèle"
          },
          "updated_date": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp de dernière mise à jour du modèle"
          }
        },
        "required": [
          "id",
          "name",
          "created_date"
        ]
      },
      "TemplateUser": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identifiant unique de l'utilisateur du modèle"
          },
          "name": {
            "type": "string",
            "description": "Nom du destinataire (prénom et nom combinés)"
          },
          "email": {
            "type": "string",
            "format": "email",
            "description": "Adresse e-mail du destinataire"
          },
          "first_name": {
            "type": "string",
            "nullable": true,
            "description": "Prénom du destinataire"
          },
          "last_name": {
            "type": "string",
            "nullable": true,
            "description": "Nom de famille du destinataire"
          },
          "designation": {
            "type": "string",
            "enum": [
              "Signer",
              "Approver",
              "CC"
            ],
            "description": "Rôle du destinataire. Signer signe le document, Approver approuve avec des champs d'approbation, CC reçoit une copie une fois terminé."
          },
          "order": {
            "type": "integer",
            "minimum": 1,
            "description": "Ordre dans lequel le destinataire doit signer"
          },
          "phone_number": {
            "type": "string",
            "nullable": true,
            "description": "Numéro de téléphone du destinataire"
          },
          "street_address": {
            "type": "string",
            "nullable": true,
            "description": "Adresse postale du destinataire"
          },
          "city": {
            "type": "string",
            "nullable": true,
            "description": "Ville du destinataire"
          },
          "state_province": {
            "type": "string",
            "nullable": true,
            "description": "État ou province du destinataire"
          },
          "postal_code": {
            "type": "string",
            "nullable": true,
            "description": "Code postal du destinataire"
          },
          "country": {
            "type": "string",
            "nullable": true,
            "description": "Pays du destinataire"
          },
          "title": {
            "type": "string",
            "nullable": true,
            "description": "Intitulé de poste du destinataire"
          },
          "company": {
            "type": "string",
            "nullable": true,
            "description": "Nom de l'entreprise du destinataire"
          },
          "required_fields": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Liste des champs de données du destinataire requis pour l'envoi (basée sur les champs du modèle avec des correspondances variable_name). Inclut toujours 'email' et 'first_name'."
          },
          "missing_fields": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Liste des champs requis actuellement vides pour ce destinataire"
          },
          "required_read_only_fields": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "variable_name": {
                  "type": "string",
                  "nullable": true,
                  "description": "Nom de variable du champ en lecture seule"
                },
                "variable_defined_name": {
                  "type": "string",
                  "nullable": true,
                  "description": "Nom de champ lisible par un humain provenant de la définition du champ personnalisé (par exemple 'artist_name'). Présent uniquement pour les champs liés à une définition de champ personnalisé, sinon null."
                },
                "field_type": {
                  "type": "string",
                  "description": "Type du champ (text, date, etc.)"
                }
              }
            },
            "description": "Liste des champs en lecture seule obligatoires qui nécessitent des valeurs préremplies avant l'envoi"
          },
          "ready_to_send": {
            "type": "boolean",
            "description": "Indique si ce destinataire a toutes les données obligatoires renseignées pour l'envoi"
          }
        },
        "required": [
          "id",
          "first_name",
          "email",
          "designation",
          "order"
        ]
      },
      "DateFormatRules": {
        "type": "object",
        "description": "Règles de formatage pour les champs de date. Spécifie comment les valeurs de date doivent être affichées et formatées.",
        "properties": {
          "dateFormat": {
            "type": "string",
            "description": "Modèle de format de date. Utilisez des formats prédéfinis ou des modèles personnalisés avec : yyyy (année sur 4 chiffres), MM (mois sur 2 chiffres), dd (jour sur 2 chiffres), MMMM (nom complet du mois), MMM (nom abrégé du mois), HH (heure sur 24h), mm (minute), ss (seconde). Exemples : 'MM/dd/yyyy' s'affiche comme 01/31/2024, 'MMMM dd, yyyy' s'affiche comme January 31, 2024.",
            "enum": [
              "MM/dd/yyyy",
              "dd/MM/yyyy",
              "yyyy-MM-dd",
              "MMMM dd, yyyy",
              "MMM dd, yyyy",
              "dd MMMM yyyy"
            ],
            "default": "MM/dd/yyyy"
          }
        },
        "example": {
          "dateFormat": "MMMM dd, yyyy"
        }
      },
      "FileFormatRules": {
        "type": "object",
        "description": "Règles de formatage pour les champs de téléversement de fichier. Spécifie quels types de fichiers les signataires sont autorisés à téléverser.",
        "properties": {
          "acceptedFileTypes": {
            "type": "string",
            "enum": [
              "image_and_pdf",
              "image",
              "pdf"
            ],
            "default": "image_and_pdf",
            "description": "Types de fichiers acceptés pour le téléversement. 'image_and_pdf' accepte les JPG, PNG et PDF. 'image' accepte uniquement les JPG et PNG. 'pdf' accepte uniquement les PDF. Les fichiers sont validés par leurs magic bytes, pas seulement par l'extension. La taille maximale du fichier est de 10 Mo."
          }
        },
        "example": {
          "acceptedFileTypes": "image_and_pdf"
        }
      },
      "FieldValidationRules": {
        "type": "object",
        "nullable": true,
        "description": "Règles de validation pour les valeurs des champs. Réservé pour un usage futur, actuellement non appliqué pour aucun type de champ.",
        "additionalProperties": true
      },
      "TemplateField": {
        "type": "object",
        "description": "Un champ placé sur un document modèle",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identifiant unique du champ"
          },
          "type": {
            "type": "string",
            "enum": [
              "text",
              "signature",
              "date",
              "checkbox",
              "dropdown",
              "radio_buttons",
              "number",
              "text_area",
              "file",
              "initial",
              "stamp",
              "approval_signature",
              "approval_checkmark",
              "approval_date"
            ],
            "description": "Type du champ"
          },
          "required": {
            "type": "boolean",
            "description": "Indique si le champ est obligatoire"
          },
          "recipient_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID du destinataire assigné"
          },
          "variable_name": {
            "type": "string",
            "nullable": true,
            "description": "Nom de variable pour le champ (utilisé dans les modèles)"
          },
          "variable_defined_name": {
            "type": "string",
            "nullable": true,
            "description": "Nom de champ lisible par un humain provenant de la définition du champ personnalisé (par exemple 'artist_name'). Présent uniquement pour les champs liés à une définition de champ personnalisé, sinon null."
          },
          "position": {
            "type": "object",
            "description": "Position et dimensions du champ sur le document. Toutes les valeurs sont des pourcentages (0-100). Le champ doit tenir dans la page : x + width <= 100 et y + height <= 100.",
            "properties": {
              "x": {
                "type": "number",
                "minimum": 0,
                "maximum": 100,
                "description": "Coordonnée X de la position du champ (pourcentage, 0-100)"
              },
              "y": {
                "type": "number",
                "minimum": 0,
                "maximum": 100,
                "description": "Coordonnée Y de la position du champ (pourcentage, 0-100)"
              },
              "width": {
                "type": "number",
                "minimum": 0,
                "maximum": 100,
                "description": "Largeur du champ (pourcentage, 0-100). Remarque : x + width doit être <= 100"
              },
              "height": {
                "type": "number",
                "minimum": 0,
                "maximum": 100,
                "description": "Hauteur du champ (pourcentage, 0-100). Remarque : y + height doit être <= 100"
              }
            }
          },
          "page_number": {
            "type": "integer",
            "minimum": 1,
            "nullable": true,
            "description": "Numéro de la page où se trouve le champ (indexé à partir de 1). Ne doit pas dépasser le nombre total de pages du document."
          },
          "dropdown_options": {
            "nullable": true,
            "description": "Options pour les champs de type menu déroulant",
            "oneOf": [
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              {
                "type": "object"
              }
            ]
          },
          "multi_group_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID de groupe pour lier plusieurs champs de case à cocher ou de bouton radio ensemble. Les champs partageant le même multi_group_id se comportent comme un groupe mutuellement exclusif (comme des boutons radio) : en sélectionner un désélectionne automatiquement les autres du groupe. Utilisez le même UUID sur plusieurs champs pour créer un groupe où une seule option peut être sélectionnée à la fois."
          },
          "date_default": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Valeur de date par défaut pour les champs de date (format ISO 8601, par exemple '2024-01-15')"
          },
          "date_signing_default": {
            "type": "boolean",
            "description": "Utiliser la date de signature comme valeur par défaut pour les champs de date"
          },
          "format_rules": {
            "$ref": "#/components/schemas/DateFormatRules",
            "nullable": true,
            "description": "Règles de formatage, actuellement utilisées pour les champs de date afin de spécifier le format d'affichage"
          },
          "validation_rules": {
            "$ref": "#/components/schemas/FieldValidationRules"
          },
          "read_only": {
            "type": "boolean",
            "default": false,
            "description": "Indique si ce champ est en lecture seule (prérempli avant la signature)"
          },
          "read_only_value": {
            "type": "string",
            "nullable": true,
            "description": "Valeur statique pour les champs en lecture seule"
          }
        },
        "required": [
          "id",
          "type",
          "page_number"
        ]
      },
      "Reminder": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identifiant unique du rappel"
          },
          "hours": {
            "type": "integer",
            "minimum": 1,
            "description": "Nombre d'heures après l'envoi avant l'envoi du rappel"
          },
          "subject": {
            "type": "string",
            "description": "Objet de l'email pour le rappel",
            "maxLength": 255
          },
          "message": {
            "type": "string",
            "description": "Corps du message de l'email pour le rappel",
            "maxLength": 5000
          },
          "all_users": {
            "type": "boolean",
            "description": "Indique si le rappel s'applique à tous les utilisateurs"
          },
          "template_user_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "Utilisateur spécifique auquel envoyer le rappel (utilisé dans le contexte d'un modèle)"
          },
          "recipient_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "Destinataire spécifique auquel envoyer le rappel (utilisé dans le contexte d'une demande de signature, identique à template_user_id)"
          },
          "sent_on": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Horodatage du moment où le rappel a réellement été envoyé"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Horodatage de création du rappel"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "Horodatage de dernière mise à jour du rappel"
          }
        },
        "required": [
          "id",
          "hours",
          "subject",
          "message"
        ]
      },
      "SigningRequestListItem": {
        "type": "object",
        "description": "Demande de signature telle que renvoyée par l'endpoint LIST (GET /signing-requests)",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identifiant unique de la demande de signature"
          },
          "name": {
            "type": "string",
            "description": "Nom de la demande de signature",
            "maxLength": 255
          },
          "description": {
            "type": "string",
            "nullable": true,
            "description": "Description de la demande de signature"
          },
          "status": {
            "type": "string",
            "enum": [
              "not_sent",
              "in_progress",
              "finished",
              "cancelled",
              "declined",
              "deleted",
              "expired"
            ],
            "description": "Statut actuel de la demande de signature"
          },
          "document_url": {
            "type": "string",
            "format": "uri",
            "description": "URL pré-signée vers le document PDF. C'est une URL signée à durée limitée pour un accès sécurisé - voir document_url_expires_at pour l'heure d'expiration. Les URL initiales sont valides 7 jours ; les URL rafraîchies sont valides 1 heure. Demande une nouvelle récupération de la demande de signature pour obtenir une URL fraîche si elle a expiré."
          },
          "document_url_expires_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Horodatage ISO 8601 de l'expiration de document_url. Après cette heure, l'URL renverra une erreur d'accès refusé. Récupère à nouveau la demande de signature pour recevoir une nouvelle URL signée."
          },
          "page_count": {
            "type": "integer",
            "minimum": 1,
            "description": "Nombre de pages dans le document"
          },
          "expiration_hours": {
            "type": "integer",
            "minimum": 1,
            "default": 168,
            "description": "Nombre d'heures avant l'expiration de la demande de signature (par défaut : 168 = 7 jours)"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Horodatage ISO 8601 de l'expiration de la demande de signature. Calculé à partir de sent_date + expiration_hours. Null si la demande de signature n'a pas encore été envoyée ou n'a pas de expiration_hours défini."
          },
          "credit_cost": {
            "type": "integer",
            "minimum": 1,
            "default": 1,
            "description": "Nombre de crédits consommés lors de l'envoi de cette demande de signature. La valeur minimale est 1."
          },
          "template_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID du modèle si créé à partir d'un modèle"
          },
          "settings": {
            "$ref": "#/components/schemas/SigningRequestSettings"
          },
          "created_date": {
            "type": "string",
            "format": "date-time",
            "description": "Horodatage de création"
          },
          "updated_date": {
            "type": "string",
            "format": "date-time",
            "description": "Horodatage de dernière mise à jour"
          },
          "sent_date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Date d'envoi de la demande de signature"
          },
          "finished_date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Date à laquelle toutes les signatures ont été complétées"
          },
          "cancelled_date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Date d'annulation de la demande de signature"
          },
          "declined_date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Date de refus de la demande de signature"
          },
          "recipients": {
            "type": "array",
            "description": "Destinataires de la demande de signature (format simplifié)",
            "items": {
              "$ref": "#/components/schemas/SigningRequestListRecipient"
            }
          },
          "fields": {
            "type": "array",
            "description": "Champs de la demande de signature avec un objet position imbriqué",
            "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": "Nom de champ lisible provenant de la définition du champ personnalisé (par ex. 'artist_name'). Présent uniquement pour les champs liés à une définition de champ personnalisé, null sinon."
                },
                "position": {
                  "type": "object",
                  "properties": {
                    "x": {
                      "type": "number"
                    },
                    "y": {
                      "type": "number"
                    },
                    "width": {
                      "type": "number"
                    },
                    "height": {
                      "type": "number"
                    }
                  }
                },
                "value": {
                  "type": "string",
                  "nullable": true,
                  "description": "Valeur finale du champ après la signature"
                },
                "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": "Destinataire tel que renvoyé dans les réponses LIST des demandes de signature (format simplifié)",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identifiant unique du destinataire"
          },
          "name": {
            "type": "string",
            "description": "Nom complet combiné"
          },
          "email": {
            "type": "string",
            "format": "email",
            "description": "Adresse e-mail du destinataire"
          },
          "designation": {
            "type": "string",
            "enum": [
              "Signer",
              "Approver",
              "CC"
            ],
            "description": "Rôle du destinataire. Signer signe le document, Approver approuve avec des champs d'approbation, CC reçoit une copie une fois terminé."
          },
          "order": {
            "type": "integer",
            "minimum": 1,
            "description": "Ordre de signature"
          },
          "finished_date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Date à laquelle ce destinataire a terminé de signer"
          },
          "signature_details": {
            "type": "object",
            "nullable": true,
            "description": "Détails sur la signature du destinataire"
          }
        }
      },
      "SigningRequestCreateResponse": {
        "type": "object",
        "description": "Demande de signature telle que renvoyée par les endpoints CREATE (POST /signing-requests)",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identifiant unique de la demande de signature"
          },
          "name": {
            "type": "string",
            "description": "Nom de la demande de signature",
            "maxLength": 255
          },
          "description": {
            "type": "string",
            "nullable": true,
            "description": "Description de la demande de signature"
          },
          "status": {
            "type": "string",
            "enum": [
              "draft"
            ],
            "description": "Le statut est toujours 'draft' pour les demandes de signature nouvellement créées"
          },
          "document_url": {
            "type": "string",
            "format": "uri",
            "description": "URL pré-signée vers le document PDF"
          },
          "page_count": {
            "type": "integer",
            "minimum": 1,
            "description": "Nombre de pages dans le document"
          },
          "expiration_hours": {
            "type": "integer",
            "minimum": 1,
            "default": 168,
            "description": "Nombre d'heures avant l'expiration de la demande de signature (par défaut : 168 = 7 jours)"
          },
          "template_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID du modèle si créé à partir d'un modèle"
          },
          "settings": {
            "$ref": "#/components/schemas/SigningRequestSettings"
          },
          "created_date": {
            "type": "string",
            "format": "date-time",
            "description": "Horodatage de création"
          },
          "updated_date": {
            "type": "string",
            "format": "date-time",
            "description": "Horodatage de dernière mise à jour"
          },
          "sent_date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Date d'envoi de la demande de signature"
          },
          "finished_date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Date à laquelle toutes les signatures ont été complétées"
          },
          "cancelled_date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Date d'annulation de la demande de signature"
          },
          "recipients": {
            "type": "array",
            "description": "Destinataires de la demande de signature",
            "items": {
              "$ref": "#/components/schemas/SigningRequestCreateRecipient"
            }
          },
          "fields": {
            "type": "array",
            "description": "Champs de la demande de signature avec des valeurs de position à plat",
            "items": {
              "$ref": "#/components/schemas/SigningRequestCreateField"
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Avertissements optionnels de validation du format des e-mails. Présents uniquement lorsque les e-mails des destinataires ont des formats inhabituels."
          }
        },
        "required": [
          "id",
          "name",
          "status"
        ]
      },
      "SigningRequestCreateRecipient": {
        "type": "object",
        "description": "Destinataire tel que renvoyé dans les réponses CREATE des demandes de signature",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identifiant unique du destinataire"
          },
          "first_name": {
            "type": "string",
            "nullable": true,
            "description": "Prénom du destinataire"
          },
          "last_name": {
            "type": "string",
            "nullable": true,
            "description": "Nom de famille du destinataire"
          },
          "name": {
            "type": "string",
            "nullable": true,
            "description": "Nom complet combiné (construit automatiquement à partir de first_name + last_name)"
          },
          "email": {
            "type": "string",
            "format": "email",
            "description": "Adresse e-mail du destinataire"
          },
          "designation": {
            "type": "string",
            "enum": [
              "Signer",
              "Approver",
              "CC"
            ],
            "description": "Rôle du destinataire. Signer signe le document, Approver approuve avec des champs d'approbation, CC reçoit une copie une fois terminé."
          },
          "order": {
            "type": "integer",
            "minimum": 1,
            "description": "Ordre de signature"
          },
          "phone_number": {
            "type": "string",
            "nullable": true,
            "description": "Numéro de téléphone du destinataire"
          },
          "street_address": {
            "type": "string",
            "nullable": true,
            "description": "Adresse postale"
          },
          "city": {
            "type": "string",
            "nullable": true,
            "description": "Ville"
          },
          "state_province": {
            "type": "string",
            "nullable": true,
            "description": "État ou province"
          },
          "postal_code": {
            "type": "string",
            "nullable": true,
            "description": "Code postal"
          },
          "country": {
            "type": "string",
            "nullable": true,
            "description": "Pays"
          },
          "title": {
            "type": "string",
            "nullable": true,
            "description": "Intitulé du poste"
          },
          "company": {
            "type": "string",
            "nullable": true,
            "description": "Nom de l'entreprise"
          },
          "custom_fields": {
            "type": "object",
            "nullable": true,
            "description": "Paires clé-valeur personnalisées"
          },
          "finished_date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Date à laquelle ce destinataire a terminé de signer"
          }
        },
        "required": [
          "first_name",
          "email",
          "designation"
        ]
      },
      "SigningRequestCreateField": {
        "type": "object",
        "description": "Champ tel que renvoyé dans les réponses CREATE des demandes de signature (position à plat, style base de données)",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identifiant unique du champ"
          },
          "type": {
            "type": "string",
            "enum": [
              "text",
              "signature",
              "date",
              "checkbox",
              "dropdown",
              "radio_buttons",
              "number",
              "text_area",
              "file",
              "initial",
              "stamp",
              "approval_signature",
              "approval_checkmark",
              "approval_date"
            ],
            "description": "Type du champ"
          },
          "recipient_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID du destinataire assigné"
          },
          "page_number": {
            "type": "integer",
            "minimum": 1,
            "description": "Numéro de page (indexé à partir de 1)"
          },
          "x_position": {
            "type": "number",
            "description": "Coordonnée X en pourcentage (0-100)"
          },
          "y_position": {
            "type": "number",
            "description": "Coordonnée Y en pourcentage (0-100)"
          },
          "width": {
            "type": "number",
            "description": "Largeur en pourcentage (0-100)"
          },
          "height": {
            "type": "number",
            "description": "Hauteur en pourcentage (0-100)"
          },
          "required": {
            "type": "boolean",
            "description": "Indique si le champ est requis"
          },
          "read_only": {
            "type": "boolean",
            "description": "Indique si ce champ est en lecture seule"
          },
          "read_only_value": {
            "type": "string",
            "nullable": true,
            "description": "Valeur statique pour les champs en lecture seule"
          },
          "variable_name": {
            "type": "string",
            "nullable": true,
            "description": "Nom de variable pour le mappage des données préremplies"
          },
          "variable_defined_name": {
            "type": "string",
            "nullable": true,
            "description": "Nom de champ lisible provenant de la définition du champ personnalisé (par ex. 'artist_name'). Présent uniquement pour les champs liés à une définition de champ personnalisé, null sinon."
          },
          "dropdown_options": {
            "nullable": true,
            "description": "Options pour les champs déroulants",
            "oneOf": [
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              {
                "type": "object"
              }
            ]
          },
          "format_rules": {
            "type": "object",
            "nullable": true,
            "description": "Règles de formatage (par exemple, format de date)"
          },
          "validation_rules": {
            "type": "object",
            "nullable": true,
            "description": "Règles de validation pour le champ"
          },
          "date_signing_default": {
            "type": "boolean",
            "description": "Indique s'il faut utiliser la date de signature comme valeur par défaut"
          },
          "final_value": {
            "type": "string",
            "nullable": true,
            "description": "Valeur pré-remplie ou finale du champ"
          }
        },
        "required": [
          "type",
          "recipient_id",
          "page_number"
        ]
      },
      "SigningRequestDetail": {
        "type": "object",
        "description": "Demande de Signature détaillée telle que renvoyée par GET /signing-requests/{id} (structure imbriquée avec un objet status et des horodatages)",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identifiant unique de la demande de signature"
          },
          "name": {
            "type": "string",
            "description": "Nom de la demande de signature"
          },
          "template_description": {
            "type": "string",
            "nullable": true,
            "description": "Description issue du modèle"
          },
          "companies_workspaces_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID de l'espace de travail auquel appartient cette demande de signature"
          },
          "document_url": {
            "type": "string",
            "format": "uri",
            "description": "URL pré-signée vers le document PDF"
          },
          "document_url_expires_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "document_page_count": {
            "type": "integer",
            "minimum": 1,
            "description": "Nombre de pages du document"
          },
          "expiration_hours": {
            "type": "integer",
            "description": "Nombre d'heures avant l'expiration de la demande de signature"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Horodatage ISO 8601 correspondant à l'expiration de la demande de signature. Calculé à partir de sent_on + expiration_hours. Null si elle n'a pas encore été envoyée ou si aucun expiration_hours n'est défini."
          },
          "credit_cost": {
            "type": "integer",
            "description": "Crédits consommés lors de l'envoi"
          },
          "status": {
            "type": "object",
            "description": "Indicateurs de statut (plusieurs peuvent être vrais pour les états terminaux)",
            "properties": {
              "sent": {
                "type": "boolean"
              },
              "finished": {
                "type": "boolean"
              },
              "cancelled": {
                "type": "boolean"
              },
              "declined": {
                "type": "boolean"
              },
              "expired": {
                "type": "boolean"
              }
            }
          },
          "timestamps": {
            "type": "object",
            "description": "Tous les horodatages pertinents pour le cycle de vie de la demande de signature",
            "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": "Informations sur le statut de génération du certificat",
            "properties": {
              "generated": {
                "type": "boolean",
                "description": "Indique si le certificat PDF final a été généré"
              },
              "generated_on": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Horodatage de la génération du certificat"
              },
              "has_error": {
                "type": "boolean",
                "description": "Indique s'il y a eu une erreur lors de la génération du certificat"
              }
            }
          },
          "final_document_download_url": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "URL signée pour télécharger le document final signé (PDF avec certificat). L'URL expire après 1 heure."
          },
          "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 signée pour télécharger le PDF du document seul. L'URL expire après 1 heure."
          },
          "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 signée pour télécharger le PDF du certificat seul. L'URL expire après 1 heure."
          },
          "certificate_only_download_error": {
            "type": "string",
            "nullable": true,
            "enum": [
              "file_not_accessible",
              null
            ]
          }
        },
        "required": [
          "id",
          "name",
          "status",
          "companies_workspaces_id"
        ]
      },
      "SigningRequestSettings": {
        "type": "object",
        "description": "Paramètres renvoyés par les endpoints de liste et de détail des demandes de signature. Les modèles utilisent le schéma TemplateSettings (sans champs d'identité).",
        "properties": {
          "allow_download": {
            "type": "boolean",
            "description": "Indique si les destinataires peuvent télécharger le document",
            "default": true
          },
          "attach_pdf_on_finish": {
            "type": "boolean",
            "description": "Indique s'il faut joindre le PDF une fois la signature terminée",
            "default": true
          },
          "allow_editing_before_sending": {
            "type": "boolean",
            "description": "Indique si la demande de signature peut être modifiée avant l'envoi",
            "default": false
          },
          "use_signing_order": {
            "type": "boolean",
            "description": "Indique si l'ordre de signature est imposé entre les destinataires. Quand c'est vrai, les signataires reçoivent le document dans l'ordre défini par leur order. Quand c'est faux, tous les signataires reçoivent le document simultanément.",
            "default": true
          },
          "hand_drawn_only": {
            "type": "boolean",
            "description": "Lorsque cette option est activée, les signataires ne peuvent que dessiner leur signature à la main et ne peuvent pas utiliser de signatures dactylographiées",
            "default": false
          },
          "send_signing_email": {
            "type": "boolean",
            "description": "Indique s'il faut envoyer des e-mails de notification de demande de signature aux signataires",
            "default": true
          },
          "send_finish_email": {
            "type": "boolean",
            "description": "Indique s'il faut envoyer un e-mail de fin lorsque tous les signataires ont terminé",
            "default": true
          },
          "send_expiration_email": {
            "type": "boolean",
            "description": "Indique s'il faut envoyer un e-mail de notification d'expiration quand la demande expire",
            "default": true
          },
          "send_cancellation_email": {
            "type": "boolean",
            "description": "Indique s'il faut envoyer un e-mail de notification d'annulation quand la demande est annulée",
            "default": true
          },
          "require_otp_verification": {
            "type": "boolean",
            "nullable": true,
            "description": "Indique si les signataires doivent vérifier leur e-mail avec un code à usage unique avant d'accéder au document. null = hérite du paramètre de l'espace de travail/de l'entreprise.",
            "default": null
          },
          "disable_guided_navigation": {
            "type": "boolean",
            "nullable": true,
            "description": "Désactive le défilement automatique vers le prochain champ requis pendant la signature. Hérite de l'espace de travail ou de l'entreprise si non défini."
          },
          "allow_presigning_download": {
            "type": "boolean",
            "nullable": true,
            "description": "Permet aux signataires de télécharger le document original avant de signer. Hérite du paramètre de l'espace de travail ou de l'entreprise quand null."
          },
          "show_qr_code": {
            "type": "boolean",
            "nullable": true,
            "description": "Affiche un QR code sur la page de signature qui permet aux signataires de continuer sur leur téléphone. Hérite du paramètre de l'espace de travail ou de l'entreprise quand null."
          },
          "identity_editable_fields": {
            "type": "array",
            "nullable": true,
            "items": {
              "type": "string"
            },
            "description": "Champs d'identité que les signataires peuvent modifier avant de signer (par exemple [\"name\", \"company\"]). null = désactivé. Quand c'est défini, une boîte de dialogue de confirmation permet aux signataires de modifier les champs spécifiés."
          },
          "notify_identity_change_email": {
            "type": "boolean",
            "default": false,
            "description": "Envoie une notification par e-mail quand un signataire modifie son identité."
          }
        }
      },
      "TemplateSettings": {
        "type": "object",
        "description": "Paramètres renvoyés par les endpoints de modèles. Correspond à SigningRequestSettings sans les champs d'identité du signataire (identity_editable_fields, notify_identity_change_email), qui s'appliquent uniquement aux demandes de signature.",
        "properties": {
          "allow_download": {
            "type": "boolean",
            "description": "Indique si les destinataires peuvent télécharger le document",
            "default": true
          },
          "attach_pdf_on_finish": {
            "type": "boolean",
            "description": "Indique s'il faut joindre le PDF une fois la signature terminée",
            "default": true
          },
          "allow_editing_before_sending": {
            "type": "boolean",
            "description": "Indique si la demande de signature peut être modifiée avant l'envoi",
            "default": false
          },
          "use_signing_order": {
            "type": "boolean",
            "description": "Indique si l'ordre de signature est imposé entre les destinataires.",
            "default": true
          },
          "hand_drawn_only": {
            "type": "boolean",
            "description": "Lorsque cette option est activée, les signataires ne peuvent que dessiner leur signature à la main et ne peuvent pas utiliser de signatures dactylographiées",
            "default": false
          },
          "send_signing_email": {
            "type": "boolean",
            "description": "Indique s'il faut envoyer des e-mails de notification de demande de signature aux signataires",
            "default": true
          },
          "send_finish_email": {
            "type": "boolean",
            "description": "Indique s'il faut envoyer un e-mail de fin lorsque tous les signataires ont terminé",
            "default": true
          },
          "send_expiration_email": {
            "type": "boolean",
            "description": "Indique s'il faut envoyer un e-mail de notification d'expiration quand la demande expire",
            "default": true
          },
          "send_cancellation_email": {
            "type": "boolean",
            "description": "Indique s'il faut envoyer un e-mail de notification d'annulation quand la demande est annulée",
            "default": true
          },
          "require_otp_verification": {
            "type": "boolean",
            "nullable": true,
            "description": "Indique si les signataires doivent vérifier leur e-mail avec un code à usage unique avant d'accéder au document. null = hérite du paramètre de l'espace de travail/de l'entreprise.",
            "default": null
          },
          "disable_guided_navigation": {
            "type": "boolean",
            "nullable": true,
            "description": "Désactive le défilement automatique vers le prochain champ requis pendant la signature. Hérite de l'espace de travail ou de l'entreprise si non défini."
          },
          "allow_presigning_download": {
            "type": "boolean",
            "nullable": true,
            "description": "Autorise les signataires à télécharger le document original avant de signer. Hérite du paramètre de l'espace de travail ou de l'entreprise quand la valeur est null."
          },
          "show_qr_code": {
            "type": "boolean",
            "nullable": true,
            "description": "Affiche un QR code sur la page de signature qui permet aux signataires de continuer sur leur téléphone. Hérite du paramètre de l'espace de travail ou de l'entreprise quand la valeur est null."
          }
        }
      },
      "LegacyDocumentSettings": {
        "type": "object",
        "description": "Paramètres renvoyés par le endpoint déprécié POST /documents. Un ensemble réduit ; les nouvelles intégrations devraient utiliser les endpoints de demande de signature, qui renvoient SigningRequestSettings.",
        "properties": {
          "allow_download": {
            "type": "boolean",
            "description": "Indique si les destinataires peuvent télécharger le document",
            "default": true
          },
          "attach_pdf_on_finish": {
            "type": "boolean",
            "description": "Indique s'il faut joindre le PDF une fois la signature terminée",
            "default": true
          },
          "allow_editing_before_sending": {
            "type": "boolean",
            "description": "Indique si la demande de signature peut être modifiée avant l'envoi",
            "default": false
          },
          "use_signing_order": {
            "type": "boolean",
            "description": "Indique si l'ordre de signature est imposé entre les destinataires.",
            "default": true
          },
          "hand_drawn_only": {
            "type": "boolean",
            "description": "Quand activé, les signataires ne peuvent que dessiner leur signature à la main",
            "default": false
          },
          "send_signing_email": {
            "type": "boolean",
            "description": "Indique s'il faut envoyer les e-mails de notification de demande de signature aux signataires",
            "default": true
          },
          "send_finish_email": {
            "type": "boolean",
            "description": "Indique s'il faut envoyer un e-mail de finalisation quand tous les signataires ont terminé",
            "default": true
          },
          "send_expiration_email": {
            "type": "boolean",
            "description": "Indique s'il faut envoyer un e-mail de notification d'expiration quand la demande expire",
            "default": true
          },
          "send_cancellation_email": {
            "type": "boolean",
            "description": "Indique s'il faut envoyer un e-mail de notification d'annulation quand la demande est annulée",
            "default": true
          },
          "disable_guided_navigation": {
            "type": "boolean",
            "nullable": true,
            "description": "Désactive le défilement automatique vers le prochain champ requis pendant la signature. Hérite de l'espace de travail ou de l'entreprise si non défini."
          },
          "allow_presigning_download": {
            "type": "boolean",
            "nullable": true,
            "description": "Autorise les signataires à télécharger le document original avant de signer. Hérite du paramètre de l'espace de travail ou de l'entreprise quand la valeur est null."
          }
        }
      },
      "Recipient": {
        "type": "object",
        "required": [
          "first_name",
          "email",
          "designation"
        ],
        "description": "Schéma Destinataire avec comportements de construction automatique et de mapping. **Champ name** : Construit automatiquement à partir de first_name et last_name ('Prénom Nom' si les deux sont présents, sinon 'Prénom'). Les valeurs manuelles du nom sont écrasées. **Attribution de l'ordre** : TOUS les destinataires DOIVENT avoir une valeur order explicite. L'ordre détermine la séquence de signature, qui est toujours imposée. Les destinataires doivent signer dans l'ordre, les numéros les plus bas signant en premier. **Champs personnalisés** : Prend en charge à la fois la structure plate (par exemple, company_name à la racine) et la structure imbriquée (objet custom_fields). Les deux formats sont normalisés en interne. **Mapping des champs de modèle** : Lors de la création à partir d'un modèle avec des destinataires personnalisés, utilisez template_user_id ou order pour faire correspondre les utilisateurs du modèle. Seules les informations utilisateur (nom, e-mail, téléphone, etc.) peuvent être mises à jour - order et designation sont hérités du modèle. **IDs temporaires** : Pour la création basée sur un document, utilisez des IDs temporaires (format : 'temp_1', 'temp_2', etc.) pour référencer les destinataires dans les champs et les rappels avant leur création. **Destinataires en copie (CC)** : Les destinataires en copie reçoivent une copie terminée mais ne peuvent ni signer ni se voir attribuer de champs. Au moins un Signataire est requis.",
        "properties": {
          "id": {
            "type": "string",
            "description": "Identifiant unique. Pour les mises à jour : utilisez l'UUID existant. Pour la création basée sur un document : utilisez éventuellement un ID temporaire (format : 'temp_1', 'temp_2', etc.) pour référencer les destinataires dans les champs et les rappels avant la création. Les IDs temporaires sont automatiquement résolus en UUID réels dans la réponse."
          },
          "_temp_id": {
            "type": "string",
            "description": "Identifiant temporaire pour les nouveaux destinataires dans les requêtes PUT (mise à jour complète) (par exemple, 'temp_1'). Utilisez-le lors de la création de nouveaux destinataires en même temps que des destinataires existants dans des mises à jour complètes. Doit commencer par 'temp_' et être unique au sein de la requête. Non utilisé pour les requêtes POST (création) - utilisez plutôt le champ 'id'."
          },
          "template_user_id": {
            "type": "string",
            "format": "uuid",
            "description": "Lors de la création à partir d'un modèle, l'ID de l'utilisateur du modèle à mettre à jour. Si fourni, les données de ce destinataire mettront à jour l'utilisateur du modèle correspondant. Si non fourni, la correspondance se fait par ordre. Seules les infos utilisateur (nom, email, téléphone, adresse, titre, entreprise) peuvent être mises à jour - l'ordre et la désignation sont toujours hérités du modèle."
          },
          "first_name": {
            "type": "string",
            "maxLength": 100,
            "description": "Prénom du destinataire"
          },
          "last_name": {
            "type": "string",
            "maxLength": 100,
            "description": "Nom de famille du destinataire (optionnel, mais requis si vous utilisez les variables prédéfinies full_name ou last_name)"
          },
          "email": {
            "type": "string",
            "format": "email",
            "maxLength": 255,
            "description": "Adresse email du destinataire"
          },
          "designation": {
            "type": "string",
            "enum": [
              "Signer",
              "Approver",
              "CC"
            ],
            "description": "Rôle du destinataire. Signataire signe le document, Approbateur approuve avec des champs d'approbation, CC reçoit une copie une fois terminé."
          },
          "order": {
            "type": "integer",
            "minimum": 1,
            "description": "Numéro de séquence de signature. Les destinataires doivent signer dans l'ordre, les numéros les plus bas signant en premier. Ce champ est requis pour tous les destinataires."
          },
          "phone_number": {
            "type": "string",
            "maxLength": 50,
            "nullable": true,
            "description": "Numéro de téléphone du destinataire"
          },
          "street_address": {
            "type": "string",
            "maxLength": 255,
            "nullable": true,
            "description": "Adresse postale"
          },
          "city": {
            "type": "string",
            "maxLength": 100,
            "nullable": true,
            "description": "Ville"
          },
          "state_province": {
            "type": "string",
            "maxLength": 100,
            "nullable": true,
            "description": "État ou province"
          },
          "postal_code": {
            "type": "string",
            "maxLength": 20,
            "nullable": true,
            "description": "Code postal"
          },
          "country": {
            "type": "string",
            "maxLength": 100,
            "nullable": true,
            "description": "Pays"
          },
          "title": {
            "type": "string",
            "maxLength": 100,
            "nullable": true,
            "description": "Titre du poste"
          },
          "company": {
            "type": "string",
            "maxLength": 255,
            "nullable": true,
            "description": "Nom de l'entreprise"
          },
          "custom_fields": {
            "type": "object",
            "additionalProperties": true,
            "description": "Paires clé-valeur personnalisées pour des données supplémentaires sur le destinataire"
          }
        }
      },
      "Field": {
        "type": "object",
        "required": [
          "type",
          "position",
          "page_number"
        ],
        "description": "Définition de champ pour les demandes de signature. **Champs en lecture seule** : définissez read_only=true pour pré-remplir une valeur de champ que les signataires ne peuvent pas modifier. Utilisez read_only_value pour du texte statique, ou prefilled_data pour remplir automatiquement à partir des attributs du destinataire. **Fusion de champs basée sur un modèle** : lors de la création à partir d'un modèle avec un tableau fields, utilisez template_field_id (préféré) ou variable_name (repli) pour faire correspondre les champs du modèle. Seules les propriétés fournies remplacent les valeurs par défaut du modèle (mise à jour partielle). Les champs non appariés sont ignorés.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identifiant unique (à inclure pour les mises à jour, à omettre pour les nouveaux champs)"
          },
          "template_field_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID du champ du modèle à faire correspondre pour les mises à jour partielles (création basée sur un modèle uniquement). Utilisez ceci pour identifier quel champ du modèle remplacer. A priorité sur variable_name pour la correspondance."
          },
          "type": {
            "type": "string",
            "enum": [
              "signature",
              "text",
              "date",
              "checkbox",
              "dropdown",
              "initial",
              "initials",
              "text_area",
              "textarea",
              "image",
              "stamp",
              "approval_signature",
              "approval_checkmark",
              "approval_date"
            ],
            "description": "Type de champ. Accepte 'initial' ou 'initials' (normalisé en 'initial'), 'textarea' ou 'text_area' (normalisé en 'text_area')."
          },
          "position": {
            "type": "object",
            "required": [
              "x",
              "y",
              "width",
              "height"
            ],
            "description": "Le champ doit tenir dans les limites de la page : x + width <= 100 et y + height <= 100",
            "properties": {
              "x": {
                "type": "number",
                "minimum": 0,
                "maximum": 100,
                "description": "Coordonnée X en pourcentage (0-100)"
              },
              "y": {
                "type": "number",
                "minimum": 0,
                "maximum": 100,
                "description": "Coordonnée Y en pourcentage (0-100)"
              },
              "width": {
                "type": "number",
                "minimum": 0,
                "maximum": 100,
                "description": "Largeur en pourcentage (0-100). x + width doit être <= 100"
              },
              "height": {
                "type": "number",
                "minimum": 0,
                "maximum": 100,
                "description": "Hauteur en pourcentage (0-100). y + height doit être <= 100"
              }
            }
          },
          "page_number": {
            "type": "integer",
            "minimum": 1,
            "description": "Numéro de la page où se trouve le champ (indexé à partir de 1). Ne doit pas dépasser le nombre total de pages du document."
          },
          "required": {
            "type": "boolean",
            "default": false,
            "description": "Indique si le champ doit être complété"
          },
          "recipient_id": {
            "type": "string",
            "description": "ID du destinataire assigné à ce champ. Utilisez un véritable UUID pour la création ou les mises à jour basées sur un modèle, ou un ID temporaire (par ex. 'temp_1') pour la création basée sur un document afin de référencer les destinataires définis dans la même requête."
          },
          "variable_name": {
            "type": "string",
            "maxLength": 100,
            "nullable": true,
            "description": "Nom de variable pour le champ (utilisé dans les modèles). Également utilisé comme repli pour la correspondance de champs lors de la création basée sur un modèle quand template_field_id n'est pas fourni."
          },
          "variable_defined_name": {
            "type": "string",
            "maxLength": 100,
            "nullable": true,
            "description": "Nom lisible et personnalisé de définition du champ. Peut être utilisé comme alternative à variable_name pour cibler des champs lors de la création basée sur un modèle."
          },
          "dropdown_options": {
            "description": "Options pour les champs de liste déroulante",
            "oneOf": [
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              {
                "type": "object"
              }
            ]
          },
          "date_default": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Valeur de date par défaut"
          },
          "date_signing_default": {
            "type": "boolean",
            "default": false,
            "description": "Utiliser la date de signature comme valeur par défaut"
          },
          "multi_group_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID de groupe pour lier plusieurs champs de case à cocher ou de bouton radio ensemble. Les champs partageant le même multi_group_id se comportent comme un groupe mutuellement exclusif (comme des boutons radio) - en sélectionner un désélectionne automatiquement les autres du groupe. Utilisez le même UUID sur plusieurs champs pour créer un groupe où une seule option peut être sélectionnée à la fois."
          },
          "format_rules": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/DateFormatRules"
              },
              {
                "$ref": "#/components/schemas/FileFormatRules"
              },
              {
                "type": "object",
                "additionalProperties": true
              }
            ],
            "nullable": true,
            "description": "Règles de formatage pour la valeur du champ. Pour les champs de date, utilisez le schéma DateFormatRules avec la propriété dateFormat. Pour les champs de fichier, utilisez le schéma FileFormatRules avec la propriété acceptedFileTypes (image_and_pdf, image, ou pdf). Pour les champs url, utilisez { urlDisplayText: string }."
          },
          "validation_rules": {
            "$ref": "#/components/schemas/FieldValidationRules"
          },
          "read_only": {
            "type": "boolean",
            "default": false,
            "description": "Indique si ce champ est en lecture seule (pré-rempli avant la signature). Quand c'est true, le signataire ne peut pas modifier la valeur du champ. Utile pour afficher les termes du contrat, les infos du destinataire, ou d'autres données fixes."
          },
          "read_only_value": {
            "type": "string",
            "nullable": true,
            "description": "Valeur statique pour les champs en lecture seule. Prend le dessus sur prefilled_data si les deux sont spécifiés. Applicable uniquement quand read_only est true. Exemple : 'Contract #12345' ou '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": "Attribut utilisateur à auto-remplir quand read_only est true. La valeur est récupérée depuis les données du destinataire assigné au moment de la signature. Peut aussi référencer des clés custom_fields définies sur le destinataire (pas limité aux valeurs enum). Applicable uniquement quand read_only est true et que read_only_value n'est pas défini. Exemple : Mettre 'email' pour afficher l'adresse email du destinataire."
          },
          "required_conditions": {
            "$ref": "#/components/schemas/ConditionSet",
            "nullable": true,
            "description": "Règles conditionnelles pour déterminer quand ce champ est requis. Quand c'est défini, ça prend le dessus sur le flag statique 'required'. Le champ n'est requis que quand les conditions évaluent à true en fonction des valeurs d'autres champs."
          },
          "visibility_conditions": {
            "$ref": "#/components/schemas/ConditionSet",
            "nullable": true,
            "description": "Règles conditionnelles pour déterminer quand ce champ est visible. Quand c'est défini, le champ est caché sauf si les conditions évaluent à true. Les champs cachés ne sont pas validés à la soumission."
          },
          "background_color": {
            "type": "string",
            "nullable": true,
            "pattern": "^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$",
            "description": "Couleur de fond du champ sous forme de chaîne hexadécimale (ex. '#FFFDE7', '#fff'). Utile pour mettre en évidence les champs qui nécessitent de l'attention.",
            "example": "#FFFDE7"
          }
        }
      },
      "AnchorTag": {
        "type": "object",
        "required": [
          "anchor_string",
          "type",
          "recipient_id"
        ],
        "description": "Définition d'un tag d'ancrage pour le placement automatique de champs. Les tags d'ancrage sont des marqueurs de texte intégrés dans un document PDF (ex. '{{SIGN_HERE}}') qui sont automatiquement localisés et convertis en champs positionnés. Le texte d'ancrage est retiré du PDF après traitement par défaut.",
        "properties": {
          "anchor_string": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200,
            "description": "Chaîne de texte à rechercher dans le document PDF. Les patterns courants incluent '{{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": "Type de champ à placer à l'emplacement de l'ancrage"
          },
          "recipient_id": {
            "oneOf": [
              {
                "type": "integer"
              },
              {
                "type": "string"
              }
            ],
            "description": "ID du destinataire assigné à ce champ. Utilisez un ID temporaire (ex. 'temp_1') pour la création basée sur un document, ou un ordre entier pour la création basée sur un modèle.",
            "example": "temp_1"
          },
          "x_offset": {
            "type": "number",
            "description": "Décalage horizontal par rapport à la position de l'ancrage. Les unités sont déterminées par offset_units (par défaut : pourcentage de la largeur de la page).",
            "default": 0
          },
          "y_offset": {
            "type": "number",
            "description": "Décalage vertical par rapport à la position de l'ancrage. Les unités sont déterminées par offset_units (par défaut : pourcentage de la hauteur de la page).",
            "default": 0
          },
          "offset_units": {
            "type": "string",
            "enum": [
              "percent",
              "pixels"
            ],
            "default": "percent",
            "description": "Type d'unité pour x_offset et y_offset. 'percent' = pourcentage des dimensions de la page, 'pixels' = points PDF (72 DPI)."
          },
          "width": {
            "type": "number",
            "minimum": 0,
            "exclusiveMinimum": true,
            "description": "Largeur du champ en pourcentage de la largeur de la page. Les valeurs par défaut varient selon le type de champ (ex. signature=25, text=20, checkbox=3)."
          },
          "height": {
            "type": "number",
            "minimum": 0,
            "exclusiveMinimum": true,
            "description": "Hauteur du champ en pourcentage de la hauteur de la page. Les valeurs par défaut varient selon le type de champ (ex. signature=5, text=3, checkbox=3)."
          },
          "case_sensitive": {
            "type": "boolean",
            "default": false,
            "description": "Indique si la correspondance de la chaîne d'ancrage est sensible à la casse"
          },
          "match_whole_word": {
            "type": "boolean",
            "default": true,
            "description": "Indique s'il faut faire correspondre uniquement des mots entiers (délimités par des caractères non-alphanumériques)"
          },
          "ignore_if_not_present": {
            "type": "boolean",
            "default": false,
            "description": "Si true, ignore cette ancre sans erreur si elle n'est pas trouvée dans le document. Si false (par défaut), une ancre manquante provoque une erreur de validation."
          },
          "occurrence": {
            "type": "integer",
            "minimum": 0,
            "maximum": 1000,
            "default": 0,
            "description": "Quelle occurrence utiliser pour placer un champ. 0 = toutes les occurrences (par défaut), 1 = la première seulement, 2 = la deuxième seulement, etc."
          },
          "remove_anchor_text": {
            "type": "boolean",
            "default": true,
            "description": "Indique s'il faut retirer le texte d'ancrage du PDF en dessinant un rectangle blanc par-dessus"
          },
          "required": {
            "type": "boolean",
            "default": true,
            "description": "Indique si le champ doit être complété par le signataire"
          },
          "read_only": {
            "type": "boolean",
            "default": false,
            "description": "Indique si le champ est en lecture seule (pré-rempli)"
          },
          "read_only_value": {
            "type": "string",
            "nullable": true,
            "maxLength": 10000,
            "description": "Valeur statique pour les champs en lecture seule"
          },
          "variable_name": {
            "type": "string",
            "nullable": true,
            "maxLength": 255,
            "description": "Nom de variable pour le champ"
          },
          "variable_defined_name": {
            "type": "string",
            "maxLength": 100,
            "nullable": true,
            "description": "Nom de définition de champ personnalisé lisible par un humain. Peut être utilisé comme alternative à variable_name pour cibler des champs dans la création basée sur un modèle."
          },
          "background_color": {
            "type": "string",
            "nullable": true,
            "pattern": "^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$",
            "description": "Couleur de fond en hexadécimal (ex. '#FFFDE7')",
            "example": "#FFFDE7"
          },
          "dropdown_options": {
            "description": "Options pour les champs déroulants",
            "oneOf": [
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              {
                "type": "object"
              }
            ]
          },
          "date_default": {
            "type": "string",
            "nullable": true,
            "maxLength": 50,
            "description": "Valeur de date par défaut"
          },
          "date_signing_default": {
            "type": "boolean",
            "default": false,
            "description": "Utiliser la date de signature comme valeur par défaut"
          },
          "multi_group_id": {
            "type": "string",
            "nullable": true,
            "maxLength": 255,
            "description": "ID de groupe pour lier des champs checkbox/radio"
          }
        }
      },
      "ConditionSet": {
        "type": "object",
        "required": [
          "logic",
          "groups"
        ],
        "description": "Un ensemble de groupes de conditions avec une logique imbriquée. L'opérateur 'logic' externe combine les groupes, tandis que les conditions de chaque groupe utilisent l'opérateur opposé. Exemple : logic='and' signifie que tous les groupes doivent correspondre, et qu'au sein de chaque groupe n'importe quelle condition peut correspondre (OR).",
        "properties": {
          "logic": {
            "type": "string",
            "enum": [
              "and",
              "or"
            ],
            "description": "Opérateur logique pour combiner les groupes. 'and' = tous les groupes doivent correspondre, 'or' = n'importe quel groupe peut correspondre."
          },
          "groups": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ConditionGroup"
            },
            "description": "Tableau de groupes de conditions"
          }
        }
      },
      "ConditionGroup": {
        "type": "object",
        "required": [
          "conditions"
        ],
        "properties": {
          "conditions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Condition"
            },
            "description": "Tableau de conditions au sein de ce groupe. Combinées en utilisant l'opérateur logique opposé à celui du ConditionSet parent."
          }
        }
      },
      "Condition": {
        "type": "object",
        "required": [
          "field_id",
          "operator"
        ],
        "description": "Une condition unique qui évalue la valeur d'un champ.",
        "properties": {
          "field_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID du champ à évaluer"
          },
          "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": "Opérateur de comparaison. 'is_filled'/'is_empty' ne nécessitent pas de valeur. Opérateurs de texte : equals, not_equals, contains, not_contains. Opérateurs numériques/date : greater_than, less_than, greater_than_or_equal, less_than_or_equal."
          },
          "value": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "number"
              }
            ],
            "nullable": true,
            "description": "Valeur à comparer. Non requise pour les opérateurs is_filled/is_empty."
          }
        }
      },
      "SigningRequestReminder": {
        "type": "object",
        "required": [
          "hours",
          "subject",
          "message"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identifiant unique (à inclure pour les mises à jour, à omettre pour les nouveaux rappels)"
          },
          "hours": {
            "type": "integer",
            "minimum": 1,
            "description": "Heures avant l'expiration pour envoyer le rappel"
          },
          "all_users": {
            "type": "boolean",
            "default": false,
            "description": "Envoyer le rappel à tous les destinataires"
          },
          "recipient_id": {
            "type": "string",
            "nullable": true,
            "description": "ID de destinataire spécifique (requis si all_users est false). Utilisez un véritable UUID pour les destinataires existants ou un ID temporaire (par exemple, 'temp_1') pour la création basée sur un document afin de référencer des destinataires dans la même demande."
          },
          "subject": {
            "type": "string",
            "maxLength": 255,
            "description": "Objet de l'email"
          },
          "message": {
            "type": "string",
            "maxLength": 5000,
            "description": "Corps du message de l'email"
          }
        }
      },
      "DeletedRecipient": {
        "type": "object",
        "required": [
          "recipient_id",
          "field_action"
        ],
        "properties": {
          "recipient_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID du destinataire à supprimer"
          },
          "field_action": {
            "type": "string",
            "enum": [
              "delete",
              "reassign"
            ],
            "description": "Action à effectuer sur les champs assignés à ce destinataire"
          },
          "reassign_to_recipient_id": {
            "type": "string",
            "format": "uuid",
            "description": "Destinataire vers lequel réassigner les champs (requis si field_action est 'reassign')"
          }
        }
      },
      "SigningRequestUser": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identifiant unique de l'utilisateur de la demande de signature"
          },
          "name": {
            "type": "string",
            "description": "Nom du destinataire (prénom et nom combinés)"
          },
          "email": {
            "type": "string",
            "format": "email",
            "description": "Adresse email du destinataire"
          },
          "first_name": {
            "type": "string",
            "nullable": true,
            "description": "Prénom du destinataire"
          },
          "last_name": {
            "type": "string",
            "nullable": true,
            "description": "Nom du destinataire"
          },
          "designation": {
            "type": "string",
            "enum": [
              "Signer",
              "Approver",
              "CC"
            ],
            "description": "Rôle du destinataire. Le Signataire signe le document, l'Approbateur approuve avec des champs d'approbation, le CC reçoit une copie à la fin."
          },
          "order": {
            "type": "integer",
            "minimum": 1,
            "description": "Ordre de signature"
          },
          "finished_on": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Horodatage de la fin de toutes les actions de ce destinataire"
          },
          "declined_on": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Horodatage du refus de signer de ce destinataire"
          },
          "decline_reason": {
            "type": "string",
            "nullable": true,
            "description": "Raison fournie par le destinataire pour son refus"
          },
          "phone_number": {
            "type": "string",
            "nullable": true,
            "description": "Numéro de téléphone du destinataire"
          },
          "street_address": {
            "type": "string",
            "nullable": true,
            "description": "Adresse postale du destinataire"
          },
          "city": {
            "type": "string",
            "nullable": true,
            "description": "Ville du destinataire"
          },
          "state_province": {
            "type": "string",
            "nullable": true,
            "description": "État ou province du destinataire"
          },
          "postal_code": {
            "type": "string",
            "nullable": true,
            "description": "Code postal du destinataire"
          },
          "country": {
            "type": "string",
            "nullable": true,
            "description": "Pays du destinataire"
          },
          "title": {
            "type": "string",
            "nullable": true,
            "description": "Titre du poste du destinataire"
          },
          "company": {
            "type": "string",
            "nullable": true,
            "description": "Nom de l'entreprise du destinataire"
          },
          "custom_fields": {
            "type": "object",
            "nullable": true,
            "description": "Valeurs des champs personnalisés pour ce destinataire"
          },
          "required_fields": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Liste des champs de données du destinataire requis pour l'envoi (basée sur les champs avec des correspondances variable_name). Inclut toujours 'email' et 'first_name'."
          },
          "missing_fields": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Liste des champs requis actuellement vides pour ce destinataire"
          },
          "required_read_only_fields": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "variable_name": {
                  "type": "string",
                  "nullable": true,
                  "description": "Nom de variable du champ en lecture seule"
                },
                "variable_defined_name": {
                  "type": "string",
                  "nullable": true,
                  "description": "Nom de champ lisible provenant de la définition du champ personnalisé (par exemple, 'artist_name'). Présent uniquement pour les champs liés à une définition de champ personnalisé, sinon null."
                },
                "field_type": {
                  "type": "string",
                  "description": "Type du champ (text, date, etc.)"
                },
                "has_value": {
                  "type": "boolean",
                  "description": "Indique si ce champ en lecture seule a une valeur définie"
                }
              }
            },
            "description": "Liste des champs en lecture seule requis nécessitant des valeurs préremplies avant l'envoi"
          },
          "ready_to_send": {
            "type": "boolean",
            "description": "Indique si ce destinataire dispose de toutes les données requises remplies pour l'envoi"
          }
        },
        "required": [
          "id",
          "first_name",
          "email",
          "designation",
          "order"
        ]
      },
      "SigningRequestField": {
        "type": "object",
        "description": "Champ associé à une demande de signature, contenant des informations de position, de type et de valeur",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identifiant unique du champ"
          },
          "type": {
            "type": "string",
            "enum": [
              "text",
              "signature",
              "date",
              "checkbox",
              "initial",
              "dropdown",
              "radio_buttons",
              "text_area",
              "url",
              "file",
              "stamp",
              "approval_signature",
              "approval_checkmark",
              "approval_date"
            ],
            "description": "Type du champ. Alias simplifié de field_type."
          },
          "recipient_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID du destinataire assigné à ce champ. Alias simplifié de companies_workspaces_signing_requests_users_id."
          },
          "value": {
            "type": "string",
            "nullable": true,
            "description": "Valeur finale signée du champ. Alias simplifié de final_value."
          },
          "position": {
            "type": "object",
            "description": "Position et dimensions du champ sur le document. Toutes les valeurs sont des pourcentages (0-100).",
            "properties": {
              "x": {
                "type": "number",
                "nullable": true,
                "description": "Position X (pourcentage, 0-100). Alias simplifié de x_postion."
              },
              "y": {
                "type": "number",
                "nullable": true,
                "description": "Position Y (pourcentage, 0-100). Alias simplifié de y_position."
              },
              "width": {
                "type": "number",
                "nullable": true,
                "description": "Largeur (pourcentage, 0-100)."
              },
              "height": {
                "type": "number",
                "nullable": true,
                "description": "Hauteur (pourcentage, 0-100). Alias simplifié de heigh."
              }
            }
          },
          "companies_workspaces_signing_requests_id": {
            "type": "string",
            "format": "uuid",
            "description": "Déprécié : redondant avec le paramètre de chemin. ID de la demande de signature à laquelle ce champ appartient."
          },
          "companies_workspaces_signing_requests_users_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "Déprécié : utilisez 'recipient_id' à la place. ID du destinataire assigné à ce champ."
          },
          "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": "Déprécié : utilisez 'type' à la place. Type du champ."
          },
          "required": {
            "type": "boolean",
            "description": "Indique si le champ est requis."
          },
          "x_postion": {
            "type": "number",
            "nullable": true,
            "description": "Déprécié : utilisez 'position.x' à la place. Position X (remarque : le nom de la colonne contient une faute de frappe)."
          },
          "y_position": {
            "type": "number",
            "nullable": true,
            "description": "Déprécié : utilisez 'position.y' à la place. Position Y du champ."
          },
          "width": {
            "type": "number",
            "nullable": true,
            "description": "Déprécié : utilisez 'position.width' à la place. Largeur du champ."
          },
          "heigh": {
            "type": "number",
            "nullable": true,
            "description": "Déprécié : utilise plutôt 'position.height'. Hauteur (note : le nom de la colonne contient une faute de frappe)."
          },
          "page_number": {
            "type": "integer",
            "nullable": true,
            "description": "Numéro de page où se trouve le champ (indexé à partir de 1)"
          },
          "tl_position": {
            "type": "number",
            "nullable": true,
            "description": "Position du coin supérieur gauche"
          },
          "tr_position": {
            "type": "number",
            "nullable": true,
            "description": "Position du coin supérieur droit"
          },
          "bl_position": {
            "type": "number",
            "nullable": true,
            "description": "Position du coin inférieur gauche"
          },
          "br_position": {
            "type": "number",
            "nullable": true,
            "description": "Position du coin inférieur droit"
          },
          "variable_name": {
            "type": "string",
            "nullable": true,
            "description": "Nom de variable pour le mapping des données pré-remplies"
          },
          "variable_defined_name": {
            "type": "string",
            "nullable": true,
            "description": "Nom de champ lisible provenant de la définition du champ personnalisé (ex. 'artist_name'). Présent uniquement pour les champs liés à une définition de champ personnalisé, sinon null."
          },
          "final_value": {
            "type": "string",
            "nullable": true,
            "description": "Déprécié : utilise plutôt 'value'. Valeur finale signée du champ."
          },
          "date_default": {
            "type": "string",
            "nullable": true,
            "description": "Valeur de date par défaut"
          },
          "date_signing_default": {
            "type": "boolean",
            "nullable": true,
            "description": "Indique s'il faut utiliser la date de signature comme valeur par défaut."
          },
          "format_rules": {
            "type": "object",
            "nullable": true,
            "description": "Règles de formatage (ex. format de date)"
          },
          "validation_rules": {
            "type": "object",
            "nullable": true,
            "description": "Règles de validation pour le champ"
          },
          "dropdown_options": {
            "nullable": true,
            "description": "Options pour les champs de type liste déroulante",
            "oneOf": [
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              {
                "type": "object"
              }
            ]
          },
          "multi_group_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID de groupe pour lier plusieurs champs de case à cocher ou bouton radio ensemble. Les champs partageant le même multi_group_id se comportent comme un groupe mutuellement exclusif (comme des boutons radio) - sélectionner l'un désélectionne automatiquement les autres du groupe. Utilise le même UUID sur plusieurs champs pour créer un groupe où une seule option peut être sélectionnée à la fois."
          },
          "read_only": {
            "type": "boolean",
            "description": "Indique si le champ est en lecture seule."
          },
          "read_only_value": {
            "type": "string",
            "nullable": true,
            "description": "Valeur statique pour les champs en lecture seule"
          },
          "background_color": {
            "type": "string",
            "nullable": true,
            "description": "Couleur de fond en hexadécimal (ex. '#FFFDE7')"
          },
          "calculated_font_size": {
            "type": "number",
            "nullable": true,
            "description": "Taille de police calculée pour le champ"
          },
          "deleted": {
            "type": "integer",
            "enum": [
              0,
              1
            ],
            "description": "Déprécié : champ interne, sera supprimé en v2. Indicateur de suppression logique (0 = actif, 1 = supprimé)."
          }
        },
        "required": [
          "id",
          "field_type",
          "page_number"
        ]
      },
      "SendSigningRequestResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "description": "Indique si la Demande de Signature a été envoyée avec succès"
          },
          "message": {
            "type": "string",
            "description": "Message de succès"
          },
          "sentTo": {
            "type": "string",
            "format": "email",
            "description": "Adresse e-mail à laquelle la Demande de Signature a été envoyée"
          },
          "sentAt": {
            "type": "string",
            "format": "date-time",
            "description": "Horodatage de l'envoi de la demande"
          }
        }
      },
      "Webhook": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identifiant unique du Webhook"
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "URL du Webhook"
          },
          "description": {
            "type": "string",
            "nullable": true,
            "description": "Description du Webhook"
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Événements qui déclenchent ce Webhook"
          },
          "enabled": {
            "type": "boolean",
            "description": "Indique si le Webhook est activé"
          },
          "consecutive_failures": {
            "type": "integer",
            "description": "Nombre d'échecs de livraison consécutifs"
          },
          "auto_disabled_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Horodatage de la désactivation automatique du Webhook suite à des échecs"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Horodatage de création du Webhook"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "Horodatage de la dernière mise à jour du Webhook"
          }
        },
        "required": [
          "id",
          "url",
          "events",
          "enabled",
          "created_at"
        ]
      },
      "PatchSigningRequestBodySchema": {
        "oneOf": [
          {
            "type": "object",
            "required": [
              "document"
            ],
            "description": "Créer une Demande de Signature à partir d'un document PDF",
            "properties": {
              "document": {
                "type": "string",
                "format": "byte",
                "description": "Document PDF ou DOCX encodé en base64. Les fichiers DOCX sont automatiquement convertis en PDF. Le nombre de pages sera extrait automatiquement."
              },
              "name": {
                "type": "string",
                "maxLength": 255,
                "description": "Nom de la Demande de Signature"
              },
              "description": {
                "type": "string",
                "description": "Description de la Demande de Signature"
              },
              "expiration_hours": {
                "type": "integer",
                "minimum": 1,
                "default": 168,
                "description": "Nombre d'heures avant l'expiration de la Demande de Signature (par défaut : 168 = 7 jours)"
              },
              "recipients": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Recipient"
                },
                "description": "Destinataires de la Demande de Signature. Utilise des ID temporaires (ex. 'temp_1') dans le champ id pour référencer les destinataires dans fields/reminders."
              },
              "fields": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Field"
                },
                "description": "Champs à placer sur le document. Utilise recipient_id pour assigner les champs aux destinataires."
              },
              "anchor_tags": {
                "type": "array",
                "maxItems": 100,
                "items": {
                  "$ref": "#/components/schemas/AnchorTag"
                },
                "description": "Balises d'ancrage pour le placement automatique des champs. Les marqueurs de texte dans le PDF sont localisés et convertis en champs positionnés. Le texte d'ancrage est supprimé du PDF après traitement. Les champs créés à partir de balises d'ancrage sont ajoutés en plus des champs spécifiés manuellement. Disponible uniquement pour la création basée sur un document (pas basée sur un Modèle)."
              },
              "reminders": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/SigningRequestReminder"
                },
                "description": "Rappels à envoyer aux destinataires"
              },
              "settings": {
                "$ref": "#/components/schemas/SigningRequestSettings",
                "description": "Paramètres de la Demande de Signature"
              }
            }
          },
          {
            "type": "object",
            "required": [
              "template_id"
            ],
            "description": "Créer une Demande de Signature à partir d'un Modèle. Prend en charge les mises à jour partielles pour les destinataires et les champs.",
            "properties": {
              "template_id": {
                "type": "string",
                "format": "uuid",
                "description": "ID du Modèle à partir duquel créer la Demande de Signature. Le document, les champs et les destinataires par défaut seront copiés depuis le Modèle."
              },
              "name": {
                "type": "string",
                "maxLength": 255,
                "description": "Nom personnalisé pour la Demande de Signature (par défaut, le nom du Modèle si non fourni)"
              },
              "description": {
                "type": "string",
                "description": "Description personnalisée (par défaut, la description du Modèle si non fournie)"
              },
              "expiration_hours": {
                "type": "integer",
                "minimum": 1,
                "description": "Remplace le nombre d'heures d'expiration du Modèle"
              },
              "recipients": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Recipient"
                },
                "description": "Remplacements optionnels des destinataires. Utilise template_user_id (préféré) ou order (en repli) pour faire correspondre les utilisateurs du Modèle. Seules les informations utilisateur (first_name, last_name, email, phone_number, les champs d'adresse, title, company) peuvent être mises à jour - order et designation sont toujours hérités du Modèle. Les destinataires non fournis utiliseront les valeurs par défaut du Modèle."
              },
              "fields": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Field"
                },
                "description": "Surcharges de champs optionnelles pour les mises à jour partielles. Utilisez template_field_id (préféré) ou variable_name (solution de repli) pour faire correspondre les champs du modèle. Seules les propriétés fournies remplacent les valeurs par défaut du modèle. Propriétés de surcharge prises en charge : type, required, position, read_only, read_only_value, format_rules, validation_rules, dropdown_options, date_default, date_signing_default, multi_group_id. Les champs non trouvés sont ignorés. Si le tableau fields est omis, tous les champs du modèle sont utilisés tels quels."
              },
              "settings": {
                "$ref": "#/components/schemas/SigningRequestSettings",
                "description": "Remplacer les paramètres du modèle"
              }
            },
            "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": "Mettre à jour les propriétés de la demande de signature",
            "properties": {
              "name": {
                "type": "string",
                "maxLength": 255
              },
              "description": {
                "type": "string"
              },
              "document": {
                "type": "string",
                "format": "byte",
                "description": "Remplacer le document (PDF encodé en base64)"
              },
              "expiration_hours": {
                "type": "integer",
                "minimum": 1
              },
              "settings": {
                "$ref": "#/components/schemas/SigningRequestSettings"
              }
            }
          },
          "recipients": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Recipient"
            },
            "description": "Upsert des destinataires - incluez 'id' pour mettre à jour des destinataires existants, utilisez '_temp_id' (par ex. 'temp_1') pour les nouveaux destinataires afin de les référencer dans les champs et rappels au sein de la même requête"
          },
          "deleted_recipients": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DeletedRecipient"
            },
            "description": "Destinataires à supprimer et comment gérer leurs champs"
          },
          "force_remove_conditions": {
            "type": "boolean",
            "default": false,
            "description": "Lors de la suppression de destinataires dont les champs sont référencés par des conditions dans d'autres champs : si true, retire automatiquement les références de condition ; si false (par défaut), la requête sera rejetée avec une erreur listant les champs dépendants."
          },
          "fields": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Field"
            },
            "description": "Upsert des champs - incluez id pour mettre à jour, omettez id pour créer un nouveau champ"
          },
          "reminders": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SigningRequestReminder"
            },
            "description": "Upsert des rappels - incluez id pour mettre à jour, omettez id pour créer un nouveau rappel"
          }
        }
      },
      "GenerateJWTRequest": {
        "type": "object",
        "required": [
          "companies_workspaces_templates_id"
        ],
        "properties": {
          "companies_workspaces_templates_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID du modèle pour lequel générer un JWT"
          }
        }
      },
      "GenerateJWTResponse": {
        "type": "object",
        "properties": {
          "token": {
            "type": "string",
            "description": "Le jeton JWT généré"
          },
          "jwt_record_id": {
            "type": "string",
            "format": "uuid",
            "description": "Identifiant unique de cet enregistrement JWT"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "description": "Horodatage d'expiration du JWT (30 jours après la création)"
          }
        },
        "required": [
          "token",
          "expires_at"
        ]
      },
      "RevokeJWTRequest": {
        "type": "object",
        "required": [
          "jwt_id"
        ],
        "properties": {
          "jwt_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID du jeton JWT à révoquer"
          }
        }
      },
      "RevokeJWTResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "description": "Message de confirmation"
          },
          "jwt_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID du JWT révoqué"
          },
          "revoked": {
            "type": "boolean",
            "description": "Indique si le JWT a été révoqué avec succès"
          }
        },
        "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 demande de signature pour laquelle générer un JWT"
          }
        }
      },
      "GenerateSigningRequestJWTResponse": {
        "type": "object",
        "properties": {
          "jwt": {
            "type": "string",
            "description": "Le jeton JWT généré"
          },
          "jwt_id": {
            "type": "string",
            "format": "uuid",
            "description": "Identifiant unique de ce JWT"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "description": "Horodatage d'expiration du JWT (7 jours après la création)"
          },
          "signing_request_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID de la demande de signature à laquelle ce JWT est associé"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Horodatage de création du JWT"
          }
        },
        "required": [
          "jwt",
          "expires_at",
          "signing_request_id"
        ]
      },
      "RevokeSigningRequestJWTRequest": {
        "type": "object",
        "required": [
          "jwt_id"
        ],
        "properties": {
          "jwt_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID du jeton JWT à révoquer"
          }
        }
      },
      "RevokeSigningRequestJWTResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "description": "Message de confirmation"
          },
          "jwt_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID du JWT révoqué"
          },
          "revoked": {
            "type": "boolean",
            "description": "Indique si le JWT a été révoqué avec succès"
          }
        },
        "required": [
          "message"
        ]
      },
      "ColorPalette": {
        "type": "object",
        "description": "Palette de couleurs résolue pour l'expérience de signature. Toutes les valeurs sont des chaînes de couleur hexadécimales (#rrggbb).",
        "properties": {
          "primary": {
            "type": "string",
            "description": "Couleur d'action principale (boutons, liens, accents)",
            "example": "#2563eb"
          },
          "primary_fg": {
            "type": "string",
            "description": "Couleur du texte sur les éléments de couleur principale",
            "example": "#ffffff"
          },
          "background": {
            "type": "string",
            "description": "Couleur de fond de la page/du canevas",
            "example": "#1c1c21"
          },
          "foreground": {
            "type": "string",
            "description": "Couleur principale du texte",
            "example": "#ffffff"
          },
          "card": {
            "type": "string",
            "description": "Couleur de fond des cartes/panneaux",
            "example": "#22222a"
          },
          "border": {
            "type": "string",
            "description": "Couleur des bordures et séparateurs",
            "example": "#3b3b3b"
          },
          "accent": {
            "type": "string",
            "description": "Accent de l'interface de l'éditeur",
            "example": "#34eeff"
          },
          "accent_fg": {
            "type": "string",
            "description": "Premier plan sur l'accent",
            "example": "#000000"
          },
          "canvas": {
            "type": "string",
            "description": "Pourtour du canevas de document de l'éditeur",
            "example": "#0f1419"
          },
          "muted": {
            "type": "string",
            "description": "Surface atténuée (par défaut la carte résolue)",
            "example": "#22222a"
          },
          "muted_fg": {
            "type": "string",
            "description": "Texte atténué (dérivé pour la lisibilité si non défini)",
            "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": "Afficher un QR code sur la page de signature permettant aux signataires de continuer sur leur téléphone. Il s'agit de la valeur par défaut au niveau de l'entreprise ; les espaces de travail, modèles et demandes de signature peuvent la remplacer."
          }
        },
        "required": [
          "default_expiration_hours"
        ]
      },
      "WorkspaceSettings": {
        "type": "object",
        "properties": {
          "workspace_id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "description": "Nom de l'espace de travail"
          },
          "team_email": {
            "type": "string",
            "format": "email",
            "description": "Email de contact de l'espace de travail"
          },
          "timezone": {
            "type": "string",
            "description": "Fuseau horaire de l'espace de travail"
          },
          "language": {
            "type": "string",
            "description": "Langue de l'espace de travail pour les modèles d'email",
            "enum": [
              "en",
              "es",
              "it",
              "pt",
              "fr",
              "de",
              "el",
              "ru",
              "pl"
            ],
            "default": "en"
          },
          "signing_request_email_header": {
            "type": "string",
            "description": "Texte d'en-tête d'email personnalisé"
          },
          "signing_request_email_body": {
            "type": "string",
            "description": "Corps d'email HTML personnalisé"
          },
          "show_credit_cost_in_editor": {
            "type": "boolean",
            "description": "Indique s'il faut afficher le coût en crédits dans les éditeurs intégrés de modèles et de demandes de signature",
            "default": true
          },
          "require_otp_verification": {
            "type": "boolean",
            "nullable": true,
            "description": "Indique si les signataires doivent vérifier leur email via OTP avant d'accéder aux documents. null = hériter du paramètre de l'entreprise, true = exiger l'OTP, false = ne pas exiger l'OTP"
          },
          "require_terms_acceptance": {
            "type": "boolean",
            "nullable": true,
            "description": "Indique si les signataires doivent accepter les conditions avant de signer. null hérite du paramètre au niveau de l'entreprise."
          },
          "disable_guided_navigation": {
            "type": "boolean",
            "nullable": true,
            "description": "Désactiver le défilement automatique vers le prochain champ obligatoire pendant la signature. Hérite de l'espace de travail ou de l'entreprise si non défini."
          },
          "show_signature_frame": {
            "type": "boolean",
            "nullable": true,
            "description": "Indique s'il faut afficher un cadre visuel avec l'ID de Signature autour des signatures dans les PDF finalisés. null = hériter du paramètre de l'entreprise (activé par défaut), true = afficher le cadre, false = masquer le cadre"
          },
          "allow_presigning_download": {
            "type": "boolean",
            "nullable": true,
            "description": "Autoriser les signataires à télécharger le document original avant de signer. null hérite du paramètre au niveau de l'entreprise."
          },
          "show_partial_watermark": {
            "type": "boolean",
            "nullable": true,
            "description": "Afficher un filigrane EN COURS sur les téléchargements de PDF partiels lorsque tous les signataires n'ont pas terminé. null hérite du paramètre au niveau de l'entreprise."
          },
          "show_qr_code": {
            "type": "boolean",
            "nullable": true,
            "description": "Afficher un QR code sur la page de signature permettant aux signataires de continuer sur leur téléphone. null hérite du paramètre au niveau de l'entreprise."
          },
          "color_primary": {
            "type": "string",
            "nullable": true,
            "description": "Couleur primaire personnalisée (hex #rrggbb). Null pour hériter de l'entreprise.",
            "example": "#2563eb"
          },
          "color_primary_fg": {
            "type": "string",
            "nullable": true,
            "description": "Couleur de premier plan primaire personnalisée. Null pour hériter.",
            "example": "#ffffff"
          },
          "color_background": {
            "type": "string",
            "nullable": true,
            "description": "Couleur d'arrière-plan personnalisée. Null pour hériter.",
            "example": "#0f172a"
          },
          "color_foreground": {
            "type": "string",
            "nullable": true,
            "description": "Couleur de premier plan/texte personnalisée. Null pour hériter.",
            "example": "#ffffff"
          },
          "color_card": {
            "type": "string",
            "nullable": true,
            "description": "Couleur d'arrière-plan des cartes personnalisée. Null pour hériter.",
            "example": "#22222a"
          },
          "color_border": {
            "type": "string",
            "nullable": true,
            "description": "Couleur de bordure personnalisée. Null pour hériter.",
            "example": "#3b3b3b"
          },
          "color_accent": {
            "type": "string",
            "nullable": true,
            "description": "Couleur d'accent de l'interface de l'éditeur. Null pour hériter.",
            "example": "#34eeff"
          },
          "color_accent_fg": {
            "type": "string",
            "nullable": true,
            "description": "Couleur de premier plan sur les surfaces d'accent. Null pour hériter.",
            "example": "#000000"
          },
          "color_canvas": {
            "type": "string",
            "nullable": true,
            "description": "Couleur de l'entourage du canevas de document dans l'éditeur. Null pour hériter.",
            "example": "#0f1419"
          },
          "color_muted": {
            "type": "string",
            "nullable": true,
            "description": "Couleur de surface atténuée. Null pour hériter.",
            "example": "#22222a"
          },
          "color_muted_fg": {
            "type": "string",
            "nullable": true,
            "description": "Couleur de texte atténuée. Null pour hériter.",
            "example": "#b8b8b8"
          },
          "email_local_part": {
            "type": "string",
            "nullable": true,
            "description": "La partie locale (avant le @) de l'adresse email de l'expéditeur. Null pour hériter du paramètre de l'entreprise. S'applique uniquement quand un domaine personnalisé vérifié est configuré.",
            "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": "Libellés de boutons personnalisés par langue pour la vue de signature. Les clés sont des codes de langue (en, de, etc.) ; les valeurs sont des objets associant des clés de traduction à un texte personnalisé. Null pour utiliser les valeurs par défaut.",
            "additionalProperties": {
              "type": "object",
              "additionalProperties": {
                "type": "string"
              }
            }
          }
        },
        "required": [
          "workspace_id"
        ]
      },
      "WorkspaceCustomField": {
        "type": "object",
        "description": "Une définition de champ personnalisé pour un Espace de Travail",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identifiant unique"
          },
          "field_name": {
            "type": "string",
            "description": "Nom de champ lisible par machine (généré automatiquement à partir du libellé)"
          },
          "field_label": {
            "type": "string",
            "description": "Libellé d'affichage lisible par un humain"
          },
          "is_preset": {
            "type": "boolean",
            "description": "Si true, ce champ a une valeur prédéfinie pour tous les utilisateurs"
          },
          "preset_value": {
            "type": "string",
            "nullable": true,
            "description": "Valeur prédéfinie (utilisée uniquement quand 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": "Une définition de champ personnalisé pour un Modèle",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identifiant unique"
          },
          "field_name": {
            "type": "string",
            "description": "Nom de champ lisible par machine"
          },
          "field_label": {
            "type": "string",
            "description": "Libellé d'affichage lisible par un humain"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "field_name"
        ]
      },
      "SigningRequestCustomField": {
        "type": "object",
        "description": "Une définition de champ personnalisé pour une Demande de Signature",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identifiant unique"
          },
          "field_name": {
            "type": "string",
            "description": "Nom de champ lisible par machine"
          },
          "field_label": {
            "type": "string",
            "description": "Libellé d'affichage lisible par un humain"
          },
          "copied_from_template": {
            "type": "boolean",
            "description": "True si ce champ a été copié depuis un Modèle"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "field_name"
        ]
      },
      "Domain": {
        "type": "object",
        "description": "Configuration de domaine email pour l'envoi des emails de Demande de Signature",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identifiant unique du domaine"
          },
          "domain": {
            "type": "string",
            "description": "Le nom de domaine (par exemple, 'example.com')"
          },
          "verification_status": {
            "type": "integer",
            "enum": [
              0,
              1,
              2
            ],
            "description": "Statut de vérification de propriété du domaine : 0=en attente, 1=propriété vérifiée (enregistrement TXT confirmé), 2=finalisé (enregistré chez le fournisseur email)"
          },
          "domain_status": {
            "type": "integer",
            "enum": [
              0,
              1
            ],
            "description": "Statut d'envoi d'emails : 0=enregistrements DNS en attente de vérification, 1=entièrement vérifié et prêt à envoyer"
          },
          "is_primary": {
            "type": "boolean",
            "description": "Indique si c'est le domaine principal pour l'envoi d'emails depuis cet Espace de Travail"
          },
          "verification_token": {
            "type": "string",
            "description": "Jeton à ajouter comme enregistrement TXT pour la vérification de propriété du domaine. Retourné uniquement quand verification_status=0."
          },
          "resend_domain_id": {
            "type": "string",
            "nullable": true,
            "description": "ID de domaine du fournisseur email externe (usage interne)"
          },
          "dns_records": {
            "type": "array",
            "nullable": true,
            "description": "Enregistrements DNS requis pour l'envoi d'emails. Retourné uniquement après la finalisation du domaine (verification_status=2).",
            "items": {
              "$ref": "#/components/schemas/DomainDnsRecord"
            }
          },
          "date_created": {
            "type": "string",
            "format": "date-time",
            "description": "Horodatage de création du domaine"
          },
          "date_changed": {
            "type": "string",
            "format": "date-time",
            "description": "Horodatage de dernière mise à jour du domaine"
          }
        },
        "required": [
          "id",
          "domain",
          "domain_status",
          "verification_status"
        ]
      },
      "DomainDnsRecord": {
        "type": "object",
        "description": "Enregistrement DNS requis pour la vérification du domaine email",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "TXT",
              "CNAME",
              "MX"
            ],
            "description": "Type d'enregistrement DNS"
          },
          "name": {
            "type": "string",
            "description": "Nom/hôte de l'enregistrement DNS (par exemple, 'resend._domainkey' ou '@')"
          },
          "value": {
            "type": "string",
            "description": "Valeur de l'enregistrement DNS"
          },
          "ttl": {
            "type": "string",
            "description": "Durée de vie (par exemple, 'Auto' ou en secondes)"
          },
          "priority": {
            "type": "integer",
            "nullable": true,
            "description": "Priorité pour les enregistrements MX"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "verified",
              "failed"
            ],
            "description": "Statut de vérification de cet enregistrement spécifique"
          }
        }
      },
      "EmailTemplate": {
        "type": "object",
        "description": "Modèle d'email personnalisé pour les notifications de Demande de Signature",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Identifiant unique du modèle d'email"
          },
          "email_type": {
            "type": "string",
            "enum": [
              "signing_invite",
              "next_signer",
              "signing_expired",
              "signing_cancelled",
              "signing_declined"
            ],
            "description": "Type d'email pour lequel ce modèle est destiné"
          },
          "subject": {
            "type": "string",
            "description": "Ligne d'objet de l'email"
          },
          "body": {
            "type": "string",
            "description": "Corps de l'email (HTML). Prend en charge des placeholders comme {{signing_link}}, {{signer_name}}, etc."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Horodatage de création du modèle"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "Horodatage de dernière mise à jour du modèle"
          }
        },
        "required": [
          "email_type",
          "subject",
          "body"
        ]
      },
      "SignerTerms": {
        "type": "object",
        "properties": {
          "language": {
            "type": "string",
            "enum": [
              "en",
              "es",
              "it",
              "pt",
              "fr",
              "de",
              "el",
              "ru",
              "pl"
            ]
          },
          "statement_text": {
            "type": "string",
            "description": "Déclaration de consentement HTML nettoyée"
          },
          "terms_url": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "Lien externe optionnel vers les conditions"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "language",
          "statement_text"
        ]
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "Message d'erreur lisible par un humain"
          },
          "message": {
            "type": "string",
            "description": "Description détaillée de l'erreur"
          },
          "details": {
            "type": "object",
            "description": "Détails d'erreur supplémentaires",
            "additionalProperties": true
          }
        },
        "required": [
          "error"
        ]
      },
      "SigningRequestDownloadResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "finished",
              "in_progress",
              "cancelled",
              "declined",
              "expired"
            ],
            "description": "Statut de la Demande de Signature. `finished` signifie que tous les Signataires ont terminé. `in_progress` signifie que la signature est encore en cours et qu'il s'agit d'un téléchargement partiel. `cancelled`, `declined` et `expired` indiquent des états terminaux où le document est un instantané partiel pris au moment où la signature s'est arrêtée."
          },
          "is_partial": {
            "type": "boolean",
            "description": "Indique si cette URL de téléchargement pointe vers un document partiellement signé (tous les Signataires n'ont pas terminé)."
          },
          "download_url": {
            "type": "string",
            "format": "uri",
            "description": "URL pré-signée pour télécharger le document PDF. Expire au moment indiqué par `expires_at`."
          },
          "generated_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Horodatage ISO 8601 de la dernière génération du document. Pour les téléchargements partiels, c'est le moment où le PDF partiel a été créé."
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "description": "Horodatage ISO 8601 d'expiration de `download_url`. Interrogez à nouveau cet endpoint pour obtenir une URL fraîche après expiration."
          }
        },
        "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": "Métadonnées de pagination pour les réponses de type liste",
        "required": [
          "current_page",
          "page_size",
          "total_count",
          "total_pages"
        ]
      },
      "WorkspaceListResponse": {
        "type": "object",
        "description": "Liste paginée des espaces de travail",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Workspace"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "results",
          "pagination"
        ]
      },
      "TemplateListResponse": {
        "type": "object",
        "description": "Liste paginée des modèles",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Template"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "results",
          "pagination"
        ]
      },
      "SigningRequestListResponse": {
        "type": "object",
        "description": "Liste paginée des demandes de signature",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SigningRequestListItem"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "results",
          "pagination"
        ]
      },
      "WebhookListResponse": {
        "type": "object",
        "description": "Liste paginée des webhooks",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Webhook"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "results",
          "pagination"
        ]
      },
      "MessageResponse": {
        "type": "object",
        "description": "Réponse de succès simple avec un message",
        "properties": {
          "message": {
            "type": "string",
            "description": "Message de succès"
          }
        },
        "required": [
          "message"
        ]
      },
      "TemplateUserListResponse": {
        "type": "object",
        "description": "Liste des utilisateurs du modèle",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TemplateUser"
            }
          }
        },
        "required": [
          "results"
        ]
      },
      "TemplateFieldListResponse": {
        "type": "object",
        "description": "Liste des champs du modèle",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TemplateField"
            }
          }
        },
        "required": [
          "results"
        ]
      },
      "SigningRequestUserListResponse": {
        "type": "object",
        "description": "Liste des utilisateurs de la demande de signature",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SigningRequestUser"
            }
          }
        },
        "required": [
          "results"
        ]
      },
      "SigningRequestFieldListResponse": {
        "type": "object",
        "description": "Liste des champs de la demande de signature",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SigningRequestField"
            }
          }
        },
        "required": [
          "results"
        ]
      },
      "AuditTrailListResponse": {
        "type": "object",
        "description": "Liste des entrées de la piste d'audit",
        "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": "Indique si l'événement a été déclenché par un admin/API ou par un signataire"
                },
                "event": {
                  "type": "string",
                  "description": "Identifiant du type d'événement"
                },
                "description": {
                  "type": "string",
                  "description": "Description lisible de l'événement"
                },
                "actor": {
                  "type": "object",
                  "nullable": true,
                  "description": "Qui a effectué l'action (nom/email du signataire ou admin/clé API)"
                },
                "ip_address": {
                  "type": "string",
                  "nullable": true,
                  "description": "Adresse IP du signataire (événements signataire uniquement)"
                },
                "details": {
                  "type": "object",
                  "nullable": true,
                  "description": "Métadonnées supplémentaires spécifiques à l'événement"
                }
              }
            }
          }
        },
        "required": [
          "results"
        ]
      },
      "CompanyEmailTemplateListResponse": {
        "type": "object",
        "description": "Liste des modèles d'email de l'entreprise",
        "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 de l'espace de travail pour les résultats limités"
          }
        },
        "description": "Liste des domaines avec le contexte de l'espace de travail",
        "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": "Domaine créé avec les instructions de vérification",
        "required": [
          "domain",
          "verification_instructions"
        ]
      },
      "DomainDeleteResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "domain_id": {
            "type": "string",
            "format": "uuid"
          }
        },
        "description": "Confirmation de suppression du domaine",
        "required": [
          "message",
          "domain_id"
        ]
      },
      "DomainVerifyOwnershipResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "domain": {
            "$ref": "#/components/schemas/Domain"
          },
          "next_step": {
            "type": "string"
          }
        },
        "description": "Résultat de la vérification de propriété du domaine",
        "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": "Enregistrements DNS à ajouter pour l'envoi d'emails"
          },
          "next_step": {
            "type": "string"
          }
        },
        "description": "Finalisation du domaine avec les enregistrements DNS",
        "required": [
          "message",
          "domain",
          "dns_records",
          "next_step"
        ]
      },
      "DomainVerifyDnsResponse": {
        "type": "object",
        "properties": {
          "verified": {
            "type": "boolean",
            "description": "Indique si tous les enregistrements DNS sont vérifiés"
          },
          "message": {
            "type": "string"
          },
          "domain": {
            "$ref": "#/components/schemas/Domain"
          },
          "dns_records": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DomainDnsRecord"
            },
            "description": "Statut de chaque enregistrement DNS"
          }
        },
        "description": "Résultat de la vérification DNS",
        "required": [
          "verified",
          "message",
          "domain"
        ]
      },
      "DomainSetPrimaryResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "domain": {
            "$ref": "#/components/schemas/Domain"
          }
        },
        "description": "Confirmation de la mise à jour du domaine principal",
        "required": [
          "message",
          "domain"
        ]
      },
      "RotateSecretResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "new_secret": {
            "type": "string",
            "description": "Le nouveau secret de signature du webhook (chaîne hexadécimale de 64 caractères)"
          },
          "grace_period_hours": {
            "type": "integer",
            "description": "Nombre d'heures pendant lesquelles l'ancien secret reste valide en parallèle du nouveau"
          },
          "warning": {
            "type": "string",
            "description": "Rappel de mettre à jour la vérification de signature du webhook"
          }
        },
        "description": "Résultat de la rotation du secret avec période de grâce",
        "required": [
          "message",
          "new_secret",
          "grace_period_hours"
        ]
      },
      "SecretStatusResponse": {
        "type": "object",
        "properties": {
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Date de création du secret du webhook",
            "nullable": true
          },
          "last_rotated_at": {
            "type": "string",
            "format": "date-time",
            "description": "Date de la dernière rotation du secret du webhook",
            "nullable": true
          },
          "grace_period_active": {
            "type": "boolean",
            "description": "Indique si l'ancien secret est encore valide en parallèle du nouveau"
          },
          "grace_period_ends_at": {
            "type": "string",
            "format": "date-time",
            "description": "Date d'expiration de la période de grâce de l'ancien secret",
            "nullable": true
          }
        },
        "description": "Statut du secret du webhook et informations de rotation",
        "required": [
          "created_at"
        ]
      },
      "EmailTemplateDeleteResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "email_type": {
            "type": "string"
          }
        },
        "description": "Confirmation de suppression du modèle d'email",
        "required": [
          "message",
          "email_type"
        ]
      },
      "SignerTermsListResponse": {
        "type": "object",
        "properties": {
          "terms": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SignerTerms"
            }
          }
        },
        "description": "Liste des conditions signataire par langue",
        "required": [
          "terms"
        ]
      },
      "SignerTermsUpdateResponse": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "storedHtml": {
            "type": "string",
            "description": "Le HTML assaini réellement stocké"
          },
          "changed": {
            "type": "boolean",
            "description": "Indique si l'assainissement a modifié la déclaration soumise"
          }
        },
        "description": "Résultat de la mise à jour des conditions signataire",
        "required": [
          "ok"
        ]
      },
      "SignerTermsDeleteResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "language": {
            "type": "string"
          }
        },
        "description": "Confirmation de suppression des conditions signataire",
        "required": [
          "message",
          "language"
        ]
      },
      "CustomFieldListResponse": {
        "type": "object",
        "properties": {
          "custom_fields": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WorkspaceCustomField"
            }
          }
        },
        "description": "Liste des champs personnalisés",
        "required": [
          "custom_fields"
        ]
      },
      "LogoUploadResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "icon_url": {
            "type": "string",
            "format": "uri",
            "description": "URL publique du logo téléversé"
          }
        },
        "description": "Confirmation de téléversement du logo avec URL",
        "required": [
          "success",
          "icon_url"
        ]
      },
      "LogoDeleteResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          }
        },
        "description": "Confirmation de suppression du logo",
        "required": [
          "success"
        ]
      },
      "ApiKeyRegenerateResponse": {
        "type": "object",
        "properties": {
          "new_key": {
            "type": "object",
            "description": "La clé API nouvellement générée",
            "properties": {
              "api_key": {
                "type": "string",
                "description": "La valeur de la nouvelle clé API"
              },
              "created_at": {
                "type": "string",
                "format": "date-time",
                "description": "Date de création de la clé"
              }
            }
          },
          "key_type": {
            "type": "string",
            "enum": [
              "live",
              "test"
            ],
            "description": "Le type de clé qui a été régénéré"
          },
          "expiring_keys": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "api_key": {
                  "type": "string",
                  "description": "La valeur de la clé API arrivant à expiration"
                },
                "expires_at": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            },
            "description": "Liste des clés qui ont été configurées pour expirer dans 24 heures"
          },
          "workspace_id": {
            "type": "string",
            "format": "uuid"
          }
        },
        "description": "Résultat de la régénération de la clé API",
        "required": [
          "new_key",
          "key_type",
          "workspace_id"
        ]
      },
      "ApiKeyExpireResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "description": "Indique si l'opération a réussi"
          },
          "expired_keys": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "api_key": {
                  "type": "string",
                  "description": "La valeur de la clé API expirée"
                },
                "original_expires_at": {
                  "type": "string",
                  "format": "date-time",
                  "description": "Date d'expiration initialement prévue pour la clé"
                },
                "expired_at": {
                  "type": "string",
                  "format": "date-time",
                  "description": "Date à laquelle la clé a réellement expiré"
                }
              }
            },
            "description": "Liste des clés expirées avec détails"
          },
          "workspace_id": {
            "type": "string",
            "format": "uuid"
          },
          "message": {
            "type": "string",
            "description": "Message optionnel lorsqu'aucune clé en attente n'existe"
          }
        },
        "description": "Résultat de l'expiration de la clé API",
        "required": [
          "success",
          "workspace_id"
        ]
      },
      "TemplatePatchResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "updated_fields": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Retourné lors de la mise à jour des propriétés"
          },
          "user": {
            "type": "object",
            "description": "Retourné lors de la mise à jour/création d'un utilisateur"
          }
        },
        "description": "Résultat de la mise à jour partielle du modèle",
        "required": [
          "message",
          "updated_fields"
        ]
      },
      "TemplateDuplicateResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "ID de la nouvelle demande de signature créée"
          },
          "name": {
            "type": "string",
            "description": "Nom de la nouvelle demande de signature"
          },
          "description": {
            "type": "string",
            "nullable": true,
            "description": "Description de la nouvelle demande de signature"
          },
          "status": {
            "type": "string",
            "description": "Statut de la nouvelle demande de signature",
            "example": "draft"
          },
          "workspace_id": {
            "type": "string",
            "format": "uuid",
            "description": "Espace de travail auquel appartient la demande de signature"
          },
          "created_date": {
            "type": "string",
            "format": "date-time",
            "description": "Horodatage de création"
          }
        },
        "description": "Détails du modèle dupliqué",
        "required": [
          "id",
          "name",
          "status",
          "workspace_id"
        ]
      },
      "CreateAndSendResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "ID de la demande de signature"
          },
          "name": {
            "type": "string",
            "description": "Nom de la demande de signature"
          },
          "description": {
            "type": "string",
            "nullable": true,
            "description": "Description de la demande de signature"
          },
          "status": {
            "type": "string",
            "enum": [
              "sent"
            ],
            "description": "Toujours 'sent' pour ce endpoint"
          },
          "document_url": {
            "type": "string",
            "format": "uri",
            "description": "URL signée pour accéder au document"
          },
          "page_count": {
            "type": "integer",
            "description": "Nombre de pages du document"
          },
          "expiration_hours": {
            "type": "integer",
            "description": "Nombre d'heures avant expiration"
          },
          "settings": {
            "$ref": "#/components/schemas/SigningRequestSettings"
          },
          "created_date": {
            "type": "string",
            "format": "date-time"
          },
          "sent_date": {
            "type": "string",
            "format": "date-time",
            "description": "Date d'envoi de la demande"
          },
          "template_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "first_signer": {
            "type": "object",
            "description": "Détails du premier signataire ayant reçu l'email",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "name": {
                "type": "string"
              },
              "email": {
                "type": "string",
                "format": "email"
              },
              "signing_link": {
                "type": "string",
                "format": "uri",
                "description": "Lien direct pour que le signataire accède à la vue de signature"
              }
            }
          },
          "recipients": {
            "type": "array",
            "description": "Tous les destinataires avec leurs véritables UUID",
            "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": "Tous les champs avec les véritables UUID de destinataire",
            "items": {
              "$ref": "#/components/schemas/Field"
            }
          },
          "credits_remaining": {
            "type": "integer",
            "description": "Crédits restants pour l'entreprise après déduction"
          }
        },
        "description": "Demande de signature créée et envoyée",
        "required": [
          "id",
          "name",
          "status"
        ]
      },
      "CreateAndSendValidationError": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          },
          "code": {
            "type": "string",
            "description": "Code d'erreur exploitable par une machine",
            "example": "VALIDATION_ERROR"
          },
          "phase": {
            "type": "string",
            "enum": [
              "create_validation",
              "send_validation"
            ],
            "description": "Quelle phase de validation a échoué"
          },
          "validation_errors": {
            "type": "array",
            "description": "Erreurs de validation détaillées pour la phase d'envoi",
            "items": {
              "type": "object",
              "properties": {
                "recipient_index": {
                  "type": "integer",
                  "description": "Index du destinataire (base 1)"
                },
                "recipient_email": {
                  "type": "string"
                },
                "missing_fields": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  },
                  "description": "Liste des champs requis manquants"
                }
              }
            }
          }
        },
        "description": "Erreur de validation lors du 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": "Erreur de crédits insuffisants",
        "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": "Erreur d'entité non traitable",
        "required": [
          "error",
          "code"
        ]
      },
      "SigningRequestUpdateResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "ID de la demande de signature (pour compatibilité ascendante)"
          },
          "name": {
            "type": "string",
            "description": "Nom de la demande de signature (pour compatibilité ascendante)"
          },
          "signing_request": {
            "type": "object",
            "description": "Résumé de la demande de signature mise à jour (sous-ensemble du schéma complet SigningRequest)",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid",
                "description": "ID de la demande de signature"
              },
              "name": {
                "type": "string",
                "description": "Nom de la demande de signature"
              },
              "description": {
                "type": "string",
                "nullable": true,
                "description": "Description de la demande de signature (mappée depuis template_description)"
              },
              "document_url": {
                "type": "string",
                "format": "uri",
                "description": "URL pré-signée vers le document PDF"
              },
              "document_url_expires_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Quand l'URL du document expire"
              },
              "document_page_count": {
                "type": "integer",
                "description": "Nombre de pages dans le document"
              },
              "status": {
                "type": "string",
                "description": "Statut actuel de la demande de signature"
              },
              "expiration_hours": {
                "type": "integer",
                "description": "Heures avant l'expiration de la demande de signature"
              },
              "settings": {
                "type": "object",
                "description": "Sous-ensemble des paramètres de la demande de signature renvoyé dans la réponse PUT",
                "properties": {
                  "allow_download": {
                    "type": "boolean",
                    "description": "Indique si les destinataires peuvent télécharger le document"
                  },
                  "attach_pdf_on_finish": {
                    "type": "boolean",
                    "description": "Indique si le PDF doit être joint à la fin"
                  },
                  "hand_drawn_only": {
                    "type": "boolean",
                    "description": "Indique si seules les signatures manuscrites sont autorisées"
                  }
                }
              },
              "template_id": {
                "type": "string",
                "format": "uuid",
                "nullable": true,
                "description": "ID du modèle si créé à partir d'un modèle"
              },
              "expires_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Horodatage ISO 8601 de l'expiration de la demande de signature"
              },
              "created_date": {
                "type": "string",
                "format": "date-time",
                "description": "Horodatage de création"
              },
              "sent_date": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Quand la demande de signature a été envoyée"
              },
              "finished_date": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Quand toutes les signatures ont été complétées"
              },
              "cancelled_date": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Quand la demande de signature a été annulée"
              }
            }
          },
          "recipients": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Recipient"
            },
            "description": "Liste mise à jour des destinataires"
          },
          "reminders": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Reminder"
            },
            "description": "Liste mise à jour des rappels"
          },
          "summary": {
            "type": "object",
            "description": "Résumé de tous les changements effectués dans cette mise à jour",
            "properties": {
              "properties_updated": {
                "type": "boolean",
                "description": "Indique si des propriétés ont été mises à jour"
              },
              "recipients_created": {
                "type": "integer",
                "description": "Nombre de nouveaux destinataires créés"
              },
              "recipients_updated": {
                "type": "integer",
                "description": "Nombre de destinataires existants mis à jour"
              },
              "recipients_deleted": {
                "type": "integer",
                "description": "Nombre de destinataires supprimés en soft-delete"
              },
              "fields_created": {
                "type": "integer",
                "description": "Nombre de nouveaux champs créés"
              },
              "fields_updated": {
                "type": "integer",
                "description": "Nombre de champs existants mis à jour"
              },
              "fields_reassigned": {
                "type": "integer",
                "description": "Nombre de champs réassignés à un autre destinataire"
              },
              "fields_deleted": {
                "type": "integer",
                "description": "Nombre de champs supprimés en soft-delete"
              },
              "reminders_created": {
                "type": "integer",
                "description": "Nombre de nouveaux rappels créés"
              },
              "reminders_updated": {
                "type": "integer",
                "description": "Nombre de rappels existants mis à jour"
              },
              "warnings": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "Avertissements de format d'email pour les destinataires (non bloquants)"
              }
            }
          }
        },
        "description": "Résultat de la mise à jour de la demande de signature",
        "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": "Erreur de validation lors de la mise à jour de la demande de signature",
        "required": [
          "error"
        ]
      },
      "SigningRequestDeleteResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "signing_request_id": {
            "type": "string",
            "format": "uuid"
          },
          "deleted_on": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "Confirmation de suppression de la demande de signature",
        "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": "Nombre d'emails de notification d'annulation envoyés aux signataires"
          }
        },
        "description": "Résultat de l'annulation de la demande de signature",
        "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": "Nombre de destinataires dont la notification de renvoi a échoué"
          },
          "recipients": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "email": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                }
              }
            }
          }
        },
        "description": "Résultat du renvoi de la demande de signature",
        "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": "Erreur de conflit de renvoi",
        "required": [
          "error",
          "code"
        ]
      },
      "TestWebhookResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "description": "Indique si le webhook de test a été livré avec succès"
          },
          "status_code": {
            "type": "integer",
            "description": "Code de statut HTTP renvoyé par le endpoint du webhook"
          },
          "webhook_event_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID de l'enregistrement de l'événement webhook"
          },
          "message": {
            "type": "string"
          },
          "headers_sent": {
            "type": "object",
            "description": "En-têtes envoyés avec la requête de webhook de test",
            "properties": {
              "X-Firma-Event": {
                "type": "string"
              },
              "X-Firma-Signature": {
                "type": "string"
              },
              "X-Firma-Delivery": {
                "type": "string"
              },
              "X-Firma-Signature-Old": {
                "type": "string",
                "description": "Présent uniquement pendant la période de grâce après la rotation du secret"
              }
            }
          }
        },
        "description": "Résultat de l'exécution du test webhook",
        "required": [
          "success",
          "status_code"
        ]
      },
      "GenerateTemplateTokenResponse": {
        "type": "object",
        "properties": {
          "token": {
            "type": "string",
            "description": "Le token JWT"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "description": "Horodatage d'expiration du token"
          },
          "jwt_record_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID de l'enregistrement en base de données pour le JWT"
          }
        },
        "description": "Token JWT généré pour le modèle",
        "required": [
          "token",
          "expires_at"
        ]
      },
      "EmailTemplateDefaultsResponse": {
        "type": "object",
        "properties": {
          "language": {
            "type": "string"
          },
          "templates": {
            "type": "object",
            "description": "Correspondance entre email_type et le modèle par défaut {subject, body}",
            "additionalProperties": {
              "type": "object",
              "properties": {
                "subject": {
                  "type": "string"
                },
                "body": {
                  "type": "string"
                }
              }
            }
          }
        },
        "description": "Modèles d'email par défaut pour une langue",
        "required": [
          "language",
          "templates"
        ]
      },
      "EmailTemplatePlaceholdersResponse": {
        "type": "object",
        "properties": {
          "placeholders": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "key": {
                  "type": "string",
                  "description": "Clé du placeholder (par ex. 'signing_link')"
                },
                "description": {
                  "type": "string",
                  "description": "Ce vers quoi ce placeholder se résout"
                }
              }
            }
          }
        },
        "description": "Placeholders de modèles d'email disponibles",
        "required": [
          "placeholders"
        ]
      },
      "WorkspaceEmailTemplateListResponse": {
        "type": "object",
        "description": "Liste des modèles d'email de l'espace de travail",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EmailTemplate"
            }
          },
          "workspace_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID de l'espace de travail"
          }
        },
        "required": [
          "results",
          "workspace_id"
        ]
      }
    }
  },
  "paths": {
    "/company": {
      "get": {
        "summary": "Récupérer les informations de l'entreprise",
        "description": "Récupère les informations sur l'entreprise authentifiée",
        "tags": [
          "Company"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Informations de l'entreprise récupérées avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de débit : 200 requêtes par minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requêtes restantes dans la fenêtre actuelle"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Horodatage Unix de la réinitialisation de la limite de débit"
              }
            },
            "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": "Mettre à jour les informations de l'entreprise",
        "description": "Met à jour tous les détails de l'entreprise. Il s'agit d'un remplacement complet nécessitant tous les champs sauf 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": "Nom de l'entreprise"
                  },
                  "language": {
                    "type": "string",
                    "enum": [
                      "en",
                      "es",
                      "it",
                      "pt",
                      "fr",
                      "de",
                      "el",
                      "ru",
                      "pl"
                    ],
                    "description": "Langue par défaut de l'entreprise"
                  },
                  "account_owner": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Nom du titulaire du compte"
                  },
                  "account_owner_email": {
                    "type": "string",
                    "format": "email",
                    "description": "Adresse email du titulaire du compte"
                  },
                  "website": {
                    "type": "string",
                    "format": "uri",
                    "description": "URL du site web de l'entreprise"
                  }
                },
                "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": "Entreprise mise à jour avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de débit : 120 requêtes par minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requêtes restantes dans la fenêtre actuelle"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Horodatage Unix de la réinitialisation de la limite de débit"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Company"
                }
              }
            }
          },
          "400": {
            "description": "Erreur de validation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "protectedFields": {
                    "summary": "Tentative de modification de champs protégés",
                    "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": "Mettre à jour partiellement les informations de l'entreprise",
        "description": "Met à jour des champs spécifiques de l'entreprise. Seuls les champs fournis seront mis à jour. Au moins un champ doit être fourni.",
        "tags": [
          "Company"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Nom de l'entreprise"
                  },
                  "language": {
                    "type": "string",
                    "enum": [
                      "en",
                      "es",
                      "it",
                      "pt",
                      "fr",
                      "de",
                      "el",
                      "ru",
                      "pl"
                    ],
                    "description": "Langue par défaut de l'entreprise"
                  },
                  "account_owner": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Nom du titulaire du compte"
                  },
                  "account_owner_email": {
                    "type": "string",
                    "format": "email",
                    "description": "Adresse email du titulaire du compte"
                  },
                  "website": {
                    "type": "string",
                    "format": "uri",
                    "description": "URL du site web de l'entreprise"
                  }
                },
                "additionalProperties": false
              },
              "example": {
                "name": "Acme Corporation Ltd",
                "website": "https://www.acme.com"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Entreprise mise à jour avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de débit : 120 requêtes par minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requêtes restantes dans la fenêtre actuelle"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Horodatage Unix de la réinitialisation de la limite de débit"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Company"
                }
              }
            }
          },
          "400": {
            "description": "Erreur de validation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "protectedFields": {
                    "summary": "Tentative de modification de champs protégés",
                    "value": {
                      "error": "The following fields cannot be modified: credits",
                      "code": "VALIDATION_ERROR"
                    }
                  },
                  "noFields": {
                    "summary": "Aucun champ fourni",
                    "value": {
                      "error": "Validation failed",
                      "details": [
                        {
                          "path": [
                            "body"
                          ],
                          "message": "No fields provided to update"
                        }
                      ]
                    }
                  },
                  "invalidEmail": {
                    "summary": "Email invalide",
                    "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": "Récupérer les paramètres de l'entreprise",
        "description": "Récupère les paramètres de l'entreprise authentifiée",
        "tags": [
          "Company"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Paramètres de l'entreprise récupérés avec succès",
            "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": "Mettre à jour les paramètres de l'entreprise",
        "description": "Met à jour les paramètres de l'entreprise. Seuls les champs fournis seront mis à jour.",
        "tags": [
          "Company"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "default_expiration_hours": {
                    "type": "integer",
                    "minimum": 1,
                    "description": "Expiration par défaut de la demande de signature en heures"
                  },
                  "require_terms_acceptance": {
                    "type": "boolean",
                    "description": "Indique si les signataires doivent accepter les conditions avant de signer"
                  },
                  "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": "Afficher un QR code sur la page de signature qui permet aux signataires de continuer sur leur téléphone. C'est le paramètre par défaut au niveau de l'entreprise ; les espaces de travail, modèles et demandes de signature peuvent le remplacer."
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Paramètres de l'entreprise mis à jour avec succès",
            "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": "Lister les domaines de l'entreprise",
        "description": "Lister tous les domaines email configurés pour l'entreprise (domaines sur l'espace de travail protégé/par défaut). Ces domaines sont utilisés comme domaine d'envoi par défaut pour tous les espaces de travail.",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Domaines de l'entreprise récupérés avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de débit : 200 requêtes par minute"
              },
              "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": "Ajouter un domaine d'entreprise",
        "description": "Ajouter un nouveau domaine email pour l'entreprise. Ceci initie le processus de vérification du domaine. Après la création, vous devez :\n1. Ajouter un enregistrement TXT à votre DNS avec le jeton de vérification\n2. Appeler POST /company/domains/{id}/verify-ownership pour vérifier la propriété du domaine\n3. Appeler POST /company/domains/{id}/finalize pour vous enregistrer auprès du fournisseur d'email\n4. Ajouter les enregistrements DNS retournés (SPF, DKIM, etc.)\n5. Appeler POST /company/domains/{id}/verify-dns pour terminer la vérification",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "domain"
                ],
                "properties": {
                  "domain": {
                    "type": "string",
                    "description": "Nom de domaine à ajouter (par ex., 'example.com'). Doit être un format de domaine valide.",
                    "example": "acme.com"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Domaine créé avec succès. Ajoutez l'enregistrement TXT de vérification à votre DNS.",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de débit : 120 requêtes par minute"
              },
              "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": "Format de domaine invalide ou le domaine existe déjà",
            "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": "Obtenir un domaine d'entreprise",
        "description": "Récupérer les détails d'un domaine d'entreprise spécifique, y compris le statut de vérification et les enregistrements DNS",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID du domaine"
          }
        ],
        "responses": {
          "200": {
            "description": "Domaine récupéré avec succès",
            "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": "Supprimer un domaine d'entreprise",
        "description": "Retirer un domaine de l'entreprise. Si le domaine est le domaine principal ou le seul domaine, l'envoi revient à l'entreprise ou à l'expéditeur par défaut.",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID du domaine"
          }
        ],
        "responses": {
          "200": {
            "description": "Domaine supprimé avec succès",
            "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": "Vérifier la propriété du domaine",
        "description": "Vérifier la propriété du domaine en contrôlant l'enregistrement TXT. Appelez ceci après avoir ajouté l'enregistrement TXT de vérification à votre DNS. La propagation DNS peut prendre jusqu'à 48 heures, mais se termine généralement en quelques minutes.",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID du domaine"
          }
        ],
        "responses": {
          "200": {
            "description": "Propriété du domaine vérifiée avec succès",
            "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": "Échec de la vérification",
            "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": "Finaliser la configuration du domaine",
        "description": "Finaliser la configuration du domaine en l'enregistrant auprès du fournisseur d'email. Ceci retourne les enregistrements DNS (SPF, DKIM, DMARC) qui doivent être ajoutés pour activer l'envoi d'emails. Ne peut être appelé qu'après vérification de la propriété du domaine.",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID du domaine"
          }
        ],
        "responses": {
          "200": {
            "description": "Domaine finalisé avec succès. Ajoutez les enregistrements DNS retournés.",
            "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": "Impossible de finaliser",
            "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": "Vérifier les enregistrements DNS",
        "description": "Vérifier que tous les enregistrements DNS requis (SPF, DKIM, DMARC) sont correctement configurés. Appelez ceci après avoir ajouté tous les enregistrements DNS de l'étape de finalisation. Une fois vérifié, le domaine est prêt à envoyer des emails.",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID du domaine"
          }
        ],
        "responses": {
          "200": {
            "description": "Résultat de la vérification DNS",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DomainVerifyDnsResponse"
                },
                "examples": {
                  "verified": {
                    "summary": "Tous les enregistrements vérifiés",
                    "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": "Certains enregistrements en attente",
                    "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": "Domaine non finalisé",
            "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": "Définir le domaine principal",
        "description": "Définir un domaine comme domaine d'envoi principal pour l'entreprise. Seuls les domaines entièrement vérifiés (domain_status=1) peuvent être définis comme principaux.",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID du domaine"
          }
        ],
        "responses": {
          "200": {
            "description": "Domaine principal mis à jour avec succès",
            "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": "Domaine non vérifié",
            "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": "Lister les espaces de travail",
        "description": "Récupérer une liste paginée des espaces de travail pour l'entreprise authentifiée",
        "tags": [
          "Workspaces"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Numéro de page pour la pagination",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "page_size",
            "in": "query",
            "description": "Nombre d'éléments par page",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "name",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filtrer par nom d'espace de travail (correspondance partielle, insensible à la casse)"
          },
          {
            "name": "protected",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "0",
                "1",
                "true",
                "false"
              ]
            },
            "description": "Filtrer par statut protégé"
          },
          {
            "name": "created_after",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Filtrer les espaces de travail créés après cette date (format ISO 8601)"
          },
          {
            "name": "created_before",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Filtrer les espaces de travail créés avant cette date (format ISO 8601)"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "name",
                "protected",
                "created_on"
              ],
              "default": "created_on"
            },
            "description": "Champ à utiliser pour le tri"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Ordre de tri"
          }
        ],
        "responses": {
          "200": {
            "description": "Espaces de travail récupérés avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de débit : 200 requêtes par minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requêtes restantes dans la fenêtre actuelle"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Horodatage Unix de la réinitialisation de la limite de débit"
              }
            },
            "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": "Erreur de validation - format de date ou paramètres de tri invalides",
            "content": {
              "application/json": {
                "examples": {
                  "invalidDate": {
                    "summary": "Format de date invalide",
                    "value": {
                      "error": "Validation failed",
                      "code": "VALIDATION_ERROR",
                      "details": [
                        {
                          "path": [
                            "created_after"
                          ],
                          "message": "created_after must be a valid ISO 8601 date"
                        }
                      ]
                    }
                  },
                  "invalidSort": {
                    "summary": "Paramètre de tri invalide",
                    "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": "Créer un nouvel espace de travail",
        "description": "Créer un nouvel espace de travail pour l'entreprise authentifiée. Tous les espaces de travail sont créés comme non protégés par défaut. Le statut protégé ne peut être défini que lors de la création du compte d'entreprise.",
        "tags": [
          "Workspaces"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Nom de l'espace de travail"
                  }
                }
              },
              "example": {
                "name": "Marketing Workspace"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Espace de travail créé avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de débit : 120 requêtes par minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Nombre de requêtes restantes dans la fenêtre actuelle"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Timestamp Unix de réinitialisation de la limite de requêtes"
              }
            },
            "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": "Récupérer un espace de travail",
        "description": "Récupère un espace de travail spécifique par ID, y compris sa clé API",
        "tags": [
          "Workspaces"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID de l'espace de travail",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Espace de travail récupéré avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de requêtes : 200 requêtes par minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Nombre de requêtes restantes dans la fenêtre actuelle"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Timestamp Unix de réinitialisation de la limite de requêtes"
              }
            },
            "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": "Mettre à jour un espace de travail",
        "description": "Met à jour les informations d'un espace de travail existant. Il s'agit d'une opération de remplacement complet nécessitant le champ name.",
        "tags": [
          "Workspaces"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID de l'espace de travail",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Nom de l'espace de travail"
                  }
                }
              },
              "example": {
                "name": "Enterprise Sales Workspace"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Espace de travail mis à jour avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de requêtes : 120 requêtes par minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Nombre de requêtes restantes dans la fenêtre actuelle"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Timestamp Unix de réinitialisation de la limite de requêtes"
              }
            },
            "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": "Mettre à jour partiellement un espace de travail",
        "description": "Met à jour des champs spécifiques de l'espace de travail. Seul le champ name peut être mis à jour via l'API. Le champ protected est en lecture seule et ne peut être défini que lors de la création du compte de l'entreprise.",
        "tags": [
          "Workspaces"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID de l'espace de travail",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Nom de l'espace de travail"
                  }
                }
              },
              "example": {
                "name": "Updated Workspace Name"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Espace de travail mis à jour avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de requêtes : 120 requêtes par minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Nombre de requêtes restantes dans la fenêtre actuelle"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Timestamp Unix de réinitialisation de la limite de requêtes"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Workspace"
                }
              }
            }
          },
          "400": {
            "description": "Erreur de validation",
            "content": {
              "application/json": {
                "examples": {
                  "protectedField": {
                    "summary": "Tentative de mise à jour d'un champ protégé",
                    "value": {
                      "error": "Validation failed",
                      "details": [
                        {
                          "path": [
                            "protected"
                          ],
                          "message": "The 'protected' field cannot be updated via API"
                        }
                      ]
                    }
                  },
                  "noFields": {
                    "summary": "Aucun champ fourni",
                    "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": "Régénérer la clé API de l'espace de travail",
        "description": "Régénère la clé API d'un espace de travail. Applique une expiration de 24 heures aux clés actives existantes et crée une nouvelle clé. Ne peut pas être utilisé sur des espaces de travail protégés. Limité à 1 requête par minute.",
        "tags": [
          "Workspaces"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID de l'espace de travail",
            "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": "Quel type de clé régénérer ('live' ou 'test'). Par défaut, 'live'. La régénération d'un type n'expire pas et n'affecte pas l'autre."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Clé API régénérée avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de requêtes : 1 requête par minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Nombre de requêtes restantes dans la fenêtre actuelle"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Timestamp Unix de réinitialisation de la limite de requêtes"
              }
            },
            "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": "Impossible de régénérer la clé pour un espace de travail protégé",
            "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": "Expirer les clés API en attente",
        "description": "Expire immédiatement toutes les clés API en attente (celles avec expires_at défini) pour un espace de travail. Utile après avoir vérifié que la nouvelle clé fonctionne correctement. Ne peut pas être utilisé sur des espaces de travail protégés. Limité à 1 requête par minute.",
        "tags": [
          "Workspaces"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID de l'espace de travail",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "key_type": {
                    "type": "string",
                    "enum": [
                      "live",
                      "test"
                    ],
                    "description": "Restreindre éventuellement l'expiration à un seul type de clé ('live' ou 'test'). Si omis, toutes les clés en attente sont expirées (comportement actuel)."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Clés en attente expirées avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de requêtes : 1 requête par minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Nombre de requêtes restantes dans la fenêtre actuelle"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Timestamp Unix de réinitialisation de la limite de requêtes"
              }
            },
            "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": "Impossible d'expirer les clés pour un espace de travail protégé",
            "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": "Lister les Modèles",
        "description": "Récupère une liste paginée de modèles",
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            },
            "description": "Numéro de page"
          },
          {
            "name": "page_size",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "description": "Éléments par page"
          },
          {
            "name": "name",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filtrer par nom de modèle (correspondance partielle, insensible à la casse)"
          },
          {
            "name": "created_after",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Filtrer les modèles créés après cette date (format ISO 8601)"
          },
          {
            "name": "created_before",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Filtrer les modèles créés avant cette date (format ISO 8601)"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "name",
                "created_on",
                "last_changed_on"
              ],
              "default": "created_on"
            },
            "description": "Champ de tri"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Ordre de tri"
          }
        ],
        "responses": {
          "200": {
            "description": "Modèles récupérés avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de requêtes : 200 requêtes par minute"
              },
              "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": "Créer un Modèle",
        "description": "Crée un nouveau modèle avec un document PDF encodé en base64. L'API extrait automatiquement le nombre de pages du document.",
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "document"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Nom du modèle",
                    "example": "Employment Contract Template"
                  },
                  "description": {
                    "type": "string",
                    "description": "Description du modèle",
                    "example": "Standard employment contract for new hires"
                  },
                  "document": {
                    "type": "string",
                    "format": "byte",
                    "description": "Document PDF ou DOCX encodé en base64. Les fichiers DOCX sont automatiquement convertis en PDF. Taille maximale : 20 Mo. L'API extrait automatiquement le nombre de pages du document. (mutuellement exclusif avec document_id)",
                    "example": "JVBERi0xLjQKJeLjz9MKMyAwIG9iago8PC9UeXBlIC9QYWdlCi9QYXJlbnQgMSAwIFIKL1Jlc291c..."
                  },
                  "expiration_hours": {
                    "type": "integer",
                    "description": "Heures avant l'expiration de la demande de signature",
                    "default": 168,
                    "example": 168
                  },
                  "settings": {
                    "type": "object",
                    "properties": {
                      "allow_editing_before_sending": {
                        "type": "boolean",
                        "default": false,
                        "description": "Autoriser la modification des champs avant l'envoi"
                      },
                      "attach_pdf_on_finish": {
                        "type": "boolean",
                        "default": true,
                        "description": "Joindre le PDF terminé à l'email de finalisation"
                      },
                      "allow_download": {
                        "type": "boolean",
                        "default": true,
                        "description": "Autoriser les destinataires à télécharger le document"
                      },
                      "hand_drawn_only": {
                        "type": "boolean",
                        "default": false,
                        "description": "Exiger des signataires qu'ils dessinent leur signature à la main plutôt que d'utiliser des signatures saisies"
                      },
                      "require_otp_verification": {
                        "type": "boolean",
                        "nullable": true,
                        "default": null,
                        "description": "Exiger des signataires qu'ils vérifient leur email avec un code à usage unique. null = hérite de l'espace de travail/l'entreprise."
                      },
                      "disable_guided_navigation": {
                        "type": "boolean",
                        "nullable": true,
                        "description": "Désactiver le défilement automatique vers le prochain champ requis pendant la signature. Hérite de l'espace de travail ou de l'entreprise si non défini."
                      },
                      "allow_presigning_download": {
                        "type": "boolean",
                        "nullable": true,
                        "description": "Autoriser les signataires à télécharger le document original avant de signer. Hérite du paramètre de l'espace de travail ou de l'entreprise si null."
                      },
                      "show_qr_code": {
                        "type": "boolean",
                        "nullable": true,
                        "description": "Affiche un QR code sur la page de signature qui permet aux signataires de continuer sur leur téléphone. Hérite du paramètre de l'espace de travail ou de l'entreprise si null."
                      }
                    }
                  },
                  "document_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "ID d'un document précédemment téléversé (mutuellement exclusif avec document). À obtenir en appelant d'abord POST /documents.",
                    "example": "123e4567-e89b-12d3-a456-426614174000"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Modèle créé avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de taux : 120 requêtes par minute"
              },
              "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": "Récupérer un Modèle",
        "description": "Récupère un modèle spécifique par ID",
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Modèle récupéré avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de taux : 200 requêtes par minute"
              },
              "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": "Mettre à Jour Partiellement un Modèle",
        "description": "Met à jour les propriétés du modèle, un seul utilisateur, OU un seul champ. Impossible de mélanger plusieurs types d'entités dans une seule requête. Utilisez PUT pour des mises à jour complètes incluant les utilisateurs, les champs et les rappels.",
        "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": "Mettre à jour les propriétés du modèle",
                    "properties": {
                      "name": {
                        "type": "string",
                        "maxLength": 255,
                        "description": "Nom du modèle"
                      },
                      "description": {
                        "type": "string",
                        "description": "Description du modèle"
                      },
                      "document": {
                        "type": "string",
                        "format": "byte",
                        "description": "PDF ou DOCX encodé en base64 pour remplacer le document. Les fichiers DOCX sont automatiquement convertis en PDF. Taille maximale : 20 Mo"
                      },
                      "expiration_hours": {
                        "type": "integer",
                        "minimum": 1,
                        "description": "Heures avant expiration"
                      },
                      "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": "Autorise les signataires à télécharger le document original avant de signer. Hérite du paramètre de l'espace de travail ou de l'entreprise si null."
                          },
                          "show_qr_code": {
                            "type": "boolean",
                            "nullable": true,
                            "description": "Affiche un QR code sur la page de signature qui permet aux signataires de continuer sur leur téléphone. Hérite du paramètre de l'espace de travail ou de l'entreprise si null."
                          }
                        }
                      }
                    }
                  },
                  {
                    "type": "object",
                    "description": "Mettre à jour ou créer un seul utilisateur",
                    "required": [
                      "user"
                    ],
                    "properties": {
                      "user": {
                        "type": "object",
                        "required": [
                          "first_name",
                          "email",
                          "designation",
                          "order"
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid",
                            "description": "À inclure pour mettre à jour un utilisateur existant, à omettre pour en créer un nouveau"
                          },
                          "first_name": {
                            "type": "string",
                            "maxLength": 255
                          },
                          "last_name": {
                            "type": "string",
                            "maxLength": 255,
                            "description": "Optionnel, mais requis si vous utilisez les variables préremplies full_name ou 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": "Mettre à jour ou créer un seul champ",
                    "required": [
                      "field"
                    ],
                    "properties": {
                      "field": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid",
                            "description": "À inclure pour mettre à jour un champ existant, à omettre pour en créer un nouveau"
                          },
                          "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": "Type de champ. Accepte 'initial' ou 'initials', 'textarea' ou 'text_area'. Requis pour les nouveaux champs. Les champs url sont automatiquement en lecture seule. Les champs file permettent aux signataires de téléverser des pièces jointes (images/PDF). Les champs stamp affichent une image préconfigurée."
                          },
                          "x": {
                            "type": "number",
                            "description": "Position X sur le document. Requis pour les nouveaux champs."
                          },
                          "y": {
                            "type": "number",
                            "description": "Position Y sur le document. Requis pour les nouveaux champs."
                          },
                          "width": {
                            "type": "number",
                            "description": "Largeur du champ. Requis pour les nouveaux champs."
                          },
                          "height": {
                            "type": "number",
                            "description": "Hauteur du champ. Requis pour les nouveaux champs."
                          },
                          "page": {
                            "type": "integer",
                            "minimum": 1,
                            "description": "Numéro de page (indexé à partir de 1). Requis pour les nouveaux champs."
                          },
                          "required": {
                            "type": "boolean",
                            "description": "Si le champ est obligatoire"
                          },
                          "assigned_to_user_id": {
                            "type": "string",
                            "format": "uuid",
                            "nullable": true,
                            "description": "ID de l'utilisateur du modèle auquel assigner le champ"
                          },
                          "variable_name": {
                            "type": "string",
                            "description": "Nom de variable pour le mapping des données préremplies"
                          },
                          "variable_defined_name": {
                            "type": "string",
                            "maxLength": 100,
                            "nullable": true,
                            "description": "Nom de définition de champ personnalisé, lisible par un humain. Peut être utilisé comme alternative à variable_name pour cibler des champs lors de la création basée sur un modèle."
                          },
                          "options": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "description": "Options pour les champs de type liste déroulante"
                          },
                          "format_rules": {
                            "type": "object",
                            "description": "Règles de format (par ex. format de date, urlDisplayText pour les champs url, acceptedFileTypes pour les champs file)"
                          },
                          "multi_group_id": {
                            "type": "string",
                            "format": "uuid",
                            "description": "ID de groupe pour les groupes de boutons radio"
                          },
                          "default_to_signing_date": {
                            "type": "boolean",
                            "description": "Pour les champs de type date, utilise la date de signature par défaut"
                          },
                          "read_only": {
                            "type": "boolean",
                            "description": "Si le champ est en lecture seule (automatiquement vrai pour les champs url)"
                          },
                          "read_only_value": {
                            "type": "string",
                            "description": "Valeur statique pour les champs en lecture seule. Pour les champs url, il s'agit de l'URL vers laquelle pointer."
                          }
                        }
                      }
                    }
                  }
                ]
              },
              "examples": {
                "update-properties": {
                  "summary": "Mettre à jour les propriétés",
                  "value": {
                    "name": "Updated Template Name",
                    "expiration_hours": 72
                  }
                },
                "create-url-field": {
                  "summary": "Créer un champ 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": "Créer un champ de téléversement de fichier",
                  "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": "Mettre à jour un champ existant",
                  "value": {
                    "field": {
                      "id": "field123-e89b-12d3-a456-426614174000",
                      "x": 120,
                      "y": 220
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Modèle partiellement mis à jour avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de taux : 120 requêtes par minute"
              },
              "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": "Mise à Jour Complète du Modèle",
        "description": "Mise à jour complète du modèle incluant les propriétés, les utilisateurs, les champs et les rappels. Prend en charge la suppression d'utilisateurs avec réassignation ou suppression des champs. Toutes les sections sont optionnelles mais au moins une doit être fournie.",
        "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": "Mettre à jour les métadonnées et les paramètres du modèle",
                    "properties": {
                      "name": {
                        "type": "string",
                        "maxLength": 255
                      },
                      "description": {
                        "type": "string"
                      },
                      "document": {
                        "type": "string",
                        "format": "byte",
                        "description": "PDF ou DOCX encodé en base64 pour remplacer le document. Les fichiers DOCX sont automatiquement convertis en PDF. Taille maximale : 20 Mo"
                      },
                      "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": "Autorise les signataires à télécharger le document original avant de signer. Hérite du paramètre de l'espace de travail ou de l'entreprise si null."
                          },
                          "show_qr_code": {
                            "type": "boolean",
                            "nullable": true,
                            "description": "Affiche un QR code sur la page de signature qui permet aux signataires de continuer sur leur téléphone. Hérite du paramètre de l'espace de travail ou de l'entreprise si null."
                          }
                        }
                      }
                    }
                  },
                  "users": {
                    "type": "array",
                    "description": "Crée ou met à jour des utilisateurs (inclure id pour mettre à jour, omettre pour créer)",
                    "items": {
                      "type": "object",
                      "required": [
                        "first_name",
                        "email",
                        "designation",
                        "order"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid",
                          "description": "À omettre pour les nouveaux utilisateurs"
                        },
                        "first_name": {
                          "type": "string"
                        },
                        "last_name": {
                          "type": "string",
                          "description": "Optionnel, mais requis si vous utilisez les variables préremplies full_name ou 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": "Lors de la suppression d'utilisateurs dont les champs sont référencés par des conditions dans d'autres champs : si true, supprime automatiquement les références de condition ; si false (par défaut), la requête sera rejetée avec une erreur."
                  },
                  "deleted_users": {
                    "type": "array",
                    "description": "Utilisateurs à supprimer avec stratégie de gestion des champs",
                    "items": {
                      "type": "object",
                      "required": [
                        "user_id",
                        "field_action"
                      ],
                      "properties": {
                        "user_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "field_action": {
                          "type": "string",
                          "enum": [
                            "delete",
                            "reassign"
                          ],
                          "description": "Que faire des champs assignés à cet utilisateur"
                        },
                        "reassign_to_user_id": {
                          "type": "string",
                          "format": "uuid",
                          "description": "Requis quand field_action vaut 'reassign'. L'utilisateur cible doit avoir la même désignation."
                        }
                      }
                    }
                  },
                  "fields": {
                    "type": "array",
                    "description": "Upsert des champs (inclure id pour mettre à jour, omettre pour créer)",
                    "items": {
                      "type": "object",
                      "required": [
                        "type",
                        "x",
                        "y",
                        "width",
                        "height",
                        "page"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid",
                          "description": "Omettre pour les nouveaux champs"
                        },
                        "type": {
                          "type": "string",
                          "enum": [
                            "signature",
                            "text",
                            "date",
                            "checkbox",
                            "dropdown",
                            "approval_signature",
                            "approval_checkmark",
                            "approval_date"
                          ]
                        },
                        "x": {
                          "type": "number",
                          "minimum": 0,
                          "maximum": 100,
                          "description": "Position X en pourcentage"
                        },
                        "y": {
                          "type": "number",
                          "minimum": 0,
                          "maximum": 100,
                          "description": "Position Y en pourcentage"
                        },
                        "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": "Pour les champs de type liste déroulante"
                        },
                        "default_to_signing_date": {
                          "type": "boolean",
                          "description": "Pour les champs de type date"
                        },
                        "multi_group_id": {
                          "type": "string",
                          "format": "uuid",
                          "description": "ID de groupe pour les groupes de cases à cocher/boutons radio mutuellement exclusifs"
                        },
                        "variable_name": {
                          "type": "string"
                        },
                        "variable_defined_name": {
                          "type": "string",
                          "maxLength": 100,
                          "nullable": true,
                          "description": "Nom de définition de champ personnalisé lisible par un humain. Peut être utilisé comme alternative à variable_name pour cibler des champs lors de la création basée sur un modèle."
                        },
                        "required_conditions": {
                          "$ref": "#/components/schemas/ConditionSet",
                          "nullable": true
                        },
                        "visibility_conditions": {
                          "$ref": "#/components/schemas/ConditionSet",
                          "nullable": true
                        }
                      }
                    }
                  },
                  "reminders": {
                    "type": "array",
                    "description": "Upsert des rappels (inclure id pour mettre à jour, omettre pour créer)",
                    "items": {
                      "type": "object",
                      "required": [
                        "hours",
                        "subject",
                        "message"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid",
                          "description": "Omettre pour les nouveaux rappels"
                        },
                        "hours": {
                          "type": "integer",
                          "minimum": 1,
                          "description": "Heures après l'envoi avant le rappel"
                        },
                        "all_users": {
                          "type": "boolean",
                          "default": false
                        },
                        "user_id": {
                          "type": "string",
                          "format": "uuid",
                          "description": "Requis si all_users vaut false"
                        },
                        "subject": {
                          "type": "string",
                          "maxLength": 255
                        },
                        "message": {
                          "type": "string",
                          "maxLength": 5000
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Modèle mis à jour avec succès. Retourne le modèle complet avec toutes ses relations.",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de taux : 120 requêtes par minute"
              },
              "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": "Supprimer un modèle",
        "description": "Suppression douce d'un modèle par ID. Cela marque le modèle comme supprimé mais conserve les données.",
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID du modèle",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Modèle supprimé avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de taux : 120 requêtes par minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requêtes restantes dans la fenêtre actuelle"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Horodatage Unix de la réinitialisation de la limite de taux"
              }
            },
            "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": "Obtenir les utilisateurs du modèle",
        "description": "Récupérer tous les destinataires/utilisateurs associés à un modèle spécifique",
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID du modèle",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Utilisateurs du modèle récupérés avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de taux : 200 requêtes par minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requêtes restantes dans la fenêtre actuelle"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Horodatage Unix de la réinitialisation de la limite de taux"
              }
            },
            "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": "Obtenir les champs du modèle",
        "description": "Récupérer tous les champs configurés pour un modèle spécifique",
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID du modèle",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Champs du modèle récupérés avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de taux : 200 requêtes par minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requêtes restantes dans la fenêtre actuelle"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Horodatage Unix de la réinitialisation de la limite de taux"
              }
            },
            "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": "Obtenir les rappels du modèle",
        "description": "Récupérer tous les rappels configurés pour un modèle spécifique",
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID du modèle",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Rappels du modèle récupérés avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de taux : 200 requêtes par minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requêtes restantes dans la fenêtre actuelle"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Horodatage Unix de la réinitialisation de la limite de taux"
              }
            },
            "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": "Remplacer le document du modèle",
        "description": "Remplace le document PDF d'un modèle existant tout en préservant tous les placements de champs. Le document de remplacement doit avoir le même nombre de pages et des dimensions de page correspondantes (avec une tolérance de 1pt) que l'original.",
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID du modèle"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "document"
                ],
                "properties": {
                  "document": {
                    "type": "string",
                    "description": "Document PDF ou DOCX encodé en base64. Les fichiers DOCX sont automatiquement convertis en PDF."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Document remplacé avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de taux : 120 requêtes par minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Template"
                }
              }
            }
          },
          "400": {
            "description": "Erreur de validation (nombre de pages incompatible, dimensions incompatibles, document invalide)",
            "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": "Dupliquer le modèle en une demande de signature",
        "description": "Crée une nouvelle demande de signature en dupliquant un modèle existant, y compris tous les champs, utilisateurs, rappels et paramètres.",
        "tags": [
          "Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID du modèle à dupliquer"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Nom personnalisé pour la nouvelle demande de signature (par défaut, le nom du modèle)"
                  }
                }
              },
              "example": {
                "name": "Q4 2025 Contract"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Modèle dupliqué avec succès en une nouvelle demande de signature",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de taux : 120 requêtes par minute"
              },
              "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": "Le modèle appartient à un espace de travail différent",
            "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": "Lister les Demandes de Signature",
        "description": "Récupérer une liste paginée des demandes de signature",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            },
            "description": "Numéro de page"
          },
          {
            "name": "page_size",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "description": "Éléments par page"
          },
          {
            "name": "name",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filtrer par nom de demande de signature (correspondance partielle, insensible à la casse)"
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "not_sent",
                "in_progress",
                "finished",
                "cancelled",
                "declined",
                "deleted",
                "expired"
              ]
            },
            "description": "Filtrer par statut de demande de signature. Prend en charge plusieurs valeurs séparées par des virgules.\n\n**Statuts disponibles :**\n- `not_sent` : Demande créée mais pas encore envoyée aux signataires\n- `in_progress` : Envoyée aux signataires mais pas terminée, annulée, refusée ou expirée\n- `finished` : Tous les signataires ont terminé\n- `cancelled` : La demande a été annulée par l'expéditeur\n- `declined` : Un signataire a refusé de signer (la demande est arrêtée)\n- `deleted` : Enregistrements supprimés en douceur (normalement masqués)\n- `expired` : Envoyée mais au-delà du délai d'expiration (sent_on + expiration_hours < maintenant)\n\n**Exemple :** `?status=in_progress,expired`\n\n**Remarque :** Le statut `expired` utilise un post-filtrage qui peut avoir des implications sur les performances avec de grands ensembles de données."
          },
          {
            "name": "created_after",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Filtrer les demandes de signature créées après cette date (format ISO 8601)"
          },
          {
            "name": "created_before",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Filtre les demandes de signature créées avant cette date (format ISO 8601)"
          },
          {
            "name": "signer_email",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filtre par adresse email du signataire (correspondance exacte)"
          },
          {
            "name": "signer_name",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filtre par nom du signataire (correspondance partielle, insensible à la casse)"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "name",
                "created_on",
                "expiration_hours",
                "sent_on",
                "finished_on"
              ],
              "default": "created_on"
            },
            "description": "Champ utilisé pour le tri"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Ordre de tri"
          }
        ],
        "responses": {
          "200": {
            "description": "Demandes de signature récupérées avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de débit : 200 requêtes par minute"
              },
              "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": "Créer une Demande de Signature",
        "description": "Crée une nouvelle demande de signature soit à partir d'un document PDF (basé sur un document), soit à partir d'un modèle existant (basé sur un modèle). Pour une création basée sur un document, allow_editing_before_sending est automatiquement défini sur true. Pour une création basée sur un modèle, les propriétés sont héritées du modèle et peuvent être surchargées.\n\n**Motif d'ID Temporaire** : Pour une création basée sur un document, tu peux référencer des destinataires avant qu'ils soient créés en utilisant des ID temporaires (format : 'temp_X' où X est un identifiant quelconque, par exemple 'temp_1', 'temp_alice'). Utilise ces ID temporaires dans recipient.id, field.recipient_id et reminder.recipient_id. L'API valide toutes les références et fait automatiquement correspondre les ID temporaires aux vrais UUID une fois les destinataires créés. La réponse ne contient que de vrais UUID.\n\n**Validation des ID Temporaires** : Les ID temporaires doivent commencer par 'temp_', être uniques parmi tous les destinataires de la requête, et toutes les références de champ/rappel doivent pointer vers des destinataires définis dans la même requête. Un format invalide, des ID en double ou des références de destinataires manquantes renvoient une erreur 400 avec des messages de validation détaillés.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/PatchSigningRequestBody"
        },
        "responses": {
          "201": {
            "description": "Demande de signature créée avec succès. La réponse peut inclure un tableau 'warnings' pour les avertissements de validation de format d'email (non bloquants).",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de débit : 120 requêtes par minute"
              },
              "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": "Entrée invalide - tu dois fournir soit 'document' soit 'template_id', pas les deux. Le document doit être un PDF valide encodé en base64 de moins de 20 Mo. Le modèle doit exister et appartenir à l'espace de travail."
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "404": {
            "description": "Modèle introuvable ou n'appartenant pas à l'espace de travail",
            "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": "Créer et Envoyer une Demande de Signature (Atomique)",
        "description": "Crée et envoie immédiatement une demande de signature en une seule opération atomique. Ce endpoint combine les fonctionnalités de POST /signing-requests et POST /signing-requests/{id}/send.\n\n**Avantages Clés :**\n- Un seul appel API au lieu de deux requêtes séparées\n- Valide toutes les exigences d'envoi AVANT de créer la demande de signature\n- Déduction de crédit atomique - facture uniquement si tout réussit\n- Renvoie status: 'sent' immédiatement avec les détails du premier signataire\n- Plus efficace (économise 1 appel API + le temps d'aller-retour)\n\n**Validation :**\n- Toutes les validations de création standard (document/modèle, destinataires, champs)\n- Validations d'envoi supplémentaires :\n  - Tous les signataires doivent avoir un first_name et un email valide\n  - Les champs en lecture seule requis doivent avoir un final_value renseigné\n  - Les champs de données prérempliées (variable_name) doivent avoir les données utilisateur correspondantes\n  - L'entreprise doit disposer de crédits suffisants (≥1)\n\n**Atomicité :**\n- Si une validation échoue, rien n'est créé\n- Le crédit n'est déduit qu'après la création réussie et avant l'envoi de l'email\n- Si l'envoi de l'email échoue après la création, la demande de signature reste au statut 'draft' et le crédit N'est PAS déduit\n\n**Motif d'ID Temporaire :** Pour une création basée sur un document, utilise des ID temporaires (format : 'temp_X') pour référencer les destinataires avant leur création. L'API valide toutes les références et fait automatiquement correspondre les ID temporaires aux vrais UUID.\n\n**Limite de Débit :** 120 requêtes/minute (identique aux opérations d'écriture)",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Nom de la demande de signature",
                    "example": "Employment Contract - John Doe"
                  },
                  "description": {
                    "type": "string",
                    "description": "Description de la demande de signature",
                    "example": "Full-time employment contract for Software Engineer position"
                  },
                  "document": {
                    "type": "string",
                    "format": "byte",
                    "description": "Document PDF ou DOCX encodé en base64 (mutuellement exclusif avec template_id et document_id). Les fichiers DOCX sont automatiquement convertis en PDF. Taille maximale : 50 Mo.",
                    "example": "JVBERi0xLjQKJeLjz9MKMyAwIG9iago8PC9UeXBlIC9QYWdlCi9QYXJlbnQgMSAwIFIKL1Jlc291c..."
                  },
                  "template_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "ID du modèle à utiliser (mutuellement exclusif avec document et document_id)",
                    "example": "123e4567-e89b-12d3-a456-426614174000"
                  },
                  "expiration_hours": {
                    "type": "integer",
                    "minimum": 1,
                    "default": 168,
                    "description": "Nombre d'heures avant l'expiration de la demande de signature (par défaut : 168 = 7 jours)",
                    "example": 168
                  },
                  "recipients": {
                    "type": "array",
                    "description": "Tableau de destinataires. Au moins un doit être un Signataire. Pour une création basée sur un document : obligatoire. Pour une création basée sur un modèle : optionnel (utilise les destinataires du modèle si omis). Utilisez template_user_id (préféré) ou order (solution de repli) pour faire correspondre les utilisateurs du modèle.",
                    "minItems": 1,
                    "items": {
                      "$ref": "#/components/schemas/Recipient"
                    }
                  },
                  "fields": {
                    "type": "array",
                    "description": "Tableau de champs à remplir (basé sur un document uniquement)",
                    "items": {
                      "type": "object",
                      "required": [
                        "type",
                        "page",
                        "x",
                        "y"
                      ],
                      "properties": {
                        "recipient_id": {
                          "type": "string",
                          "description": "ID temporaire ou UUID du destinataire assigné à ce champ",
                          "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": "Type de champ. Accepte les alias : \"initials\" (normalisé en \"initial\"), \"textarea\" (normalisé en \"text_area\"), \"radio\" (normalisé en \"radio_buttons\").",
                          "example": "signature"
                        },
                        "page": {
                          "type": "integer",
                          "minimum": 1,
                          "description": "Numéro de page du PDF (indexé à partir de 1)",
                          "example": 1
                        },
                        "x": {
                          "type": "number",
                          "description": "Coordonnée X sur la page",
                          "example": 100
                        },
                        "y": {
                          "type": "number",
                          "description": "Coordonnée Y sur la page",
                          "example": 200
                        },
                        "width": {
                          "type": "number",
                          "default": 200,
                          "example": 200
                        },
                        "height": {
                          "type": "number",
                          "default": 50,
                          "example": 50
                        },
                        "variable_name": {
                          "type": "string",
                          "description": "Nom de variable pour les données préremplies (par ex. 'phone_number', 'company'). Si défini, le champ correspondant du destinataire doit être renseigné.",
                          "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": "Nom lisible et personnalisé de la définition du champ. Peut être utilisé comme alternative à variable_name pour cibler des champs lors d'une création basée sur un modèle."
                        },
                        "required": {
                          "type": "boolean",
                          "default": false,
                          "description": "Indique si le champ est obligatoire"
                        },
                        "read_only": {
                          "type": "boolean",
                          "default": false,
                          "description": "Indique si le champ est en lecture seule (prérempli)"
                        },
                        "final_value": {
                          "type": "string",
                          "description": "Valeur préremplie pour les champs en lecture seule (obligatoire si read_only=true et required=true)",
                          "example": "Software Engineer"
                        },
                        "background_color": {
                          "type": "string",
                          "nullable": true,
                          "pattern": "^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$",
                          "description": "Couleur d'arrière-plan en hexadécimal (par ex. '#FFFDE7')",
                          "example": "#FFFDE7"
                        },
                        "dropdown_options": {
                          "description": "Options pour les champs de type liste déroulante. Obligatoire quand type vaut \"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": "Balises d'ancrage pour le placement automatique des champs. Les marqueurs de texte dans le PDF sont localisés puis convertis en champs positionnés. Le texte d'ancrage est supprimé du PDF après traitement. Les champs créés à partir des balises d'ancrage s'ajoutent aux champs spécifiés manuellement. Disponible uniquement pour la création basée sur un document (pas pour celle basée sur un modèle)."
                  },
                  "reminders": {
                    "type": "array",
                    "description": "Tableau de configurations de rappels",
                    "items": {
                      "type": "object",
                      "required": [
                        "hours_before_expiration"
                      ],
                      "properties": {
                        "hours_before_expiration": {
                          "type": "integer",
                          "minimum": 1,
                          "description": "Heures avant expiration pour l'envoi du rappel",
                          "example": 24
                        }
                      }
                    }
                  },
                  "settings": {
                    "type": "object",
                    "description": "Paramètres de la demande de signature",
                    "properties": {
                      "use_signing_order": {
                        "type": "boolean",
                        "default": true,
                        "description": "Impose l'ordre de signature basé sur recipient.order. Si false, tous les signataires reçoivent le document simultanément."
                      },
                      "allow_download": {
                        "type": "boolean",
                        "default": true,
                        "description": "Autoriser les destinataires à télécharger le document"
                      },
                      "attach_pdf_on_finish": {
                        "type": "boolean",
                        "default": true,
                        "description": "Joindre le PDF finalisé à l'e-mail de fin de signature"
                      },
                      "send_signing_email": {
                        "type": "boolean",
                        "default": true,
                        "description": "Envoyer une notification par e-mail aux signataires"
                      },
                      "send_finish_email": {
                        "type": "boolean",
                        "default": true,
                        "description": "Envoyer un e-mail quand toutes les signatures sont terminées"
                      },
                      "send_expiration_email": {
                        "type": "boolean",
                        "default": true,
                        "description": "Envoyer un e-mail quand la demande expire"
                      },
                      "send_cancellation_email": {
                        "type": "boolean",
                        "default": true,
                        "description": "Envoyer un e-mail quand la demande est annulée"
                      },
                      "hand_drawn_only": {
                        "type": "boolean",
                        "default": false,
                        "description": "Exiger que les signataires dessinent leur signature à la main plutôt que d'utiliser une signature saisie"
                      },
                      "identity_editable_fields": {
                        "type": "array",
                        "nullable": true,
                        "items": {
                          "type": "string",
                          "enum": [
                            "name",
                            "company",
                            "title",
                            "phone",
                            "address"
                          ]
                        },
                        "description": "Champs d'identité que les signataires peuvent modifier avant de signer. null = désactivé. Si défini, une boîte de dialogue de confirmation apparaît pour permettre aux signataires de modifier les champs spécifiés.",
                        "example": [
                          "name",
                          "company"
                        ]
                      },
                      "notify_identity_change_webhook": {
                        "type": "boolean",
                        "default": false,
                        "description": "Envoyer un événement webhook quand un signataire modifie son identité"
                      },
                      "notify_identity_change_email": {
                        "type": "boolean",
                        "default": false,
                        "description": "Envoyer une notification par e-mail quand un signataire modifie son identité"
                      }
                    }
                  },
                  "document_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "ID d'un document précédemment téléversé (mutuellement exclusif avec document et template_id). À obtenir en appelant d'abord POST /documents.",
                    "example": "123e4567-e89b-12d3-a456-426614174000"
                  }
                },
                "oneOf": [
                  {
                    "required": [
                      "document"
                    ]
                  },
                  {
                    "required": [
                      "template_id"
                    ]
                  }
                ]
              },
              "examples": {
                "document-based": {
                  "summary": "Créer et envoyer avec un document",
                  "value": {
                    "name": "Employment Contract - John Doe",
                    "description": "Contrat de travail à temps plein",
                    "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": "Ingénieur logiciel"
                      }
                    ],
                    "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": "Créer et envoyer à partir d'un modèle",
                  "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": "Demande de signature créée et envoyée avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de débit : 120 requêtes par minute"
              },
              "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": "Contrat de travail à temps plein",
                  "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": "Erreur de validation - entrée invalide ou données de signataire obligatoires manquantes",
            "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édits insuffisants",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientCreditsError"
                }
              }
            }
          },
          "404": {
            "description": "Modèle introuvable ou n'appartenant pas à l'espace de travail",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "L'adresse e-mail du destinataire est suspendue (rejet précédent ou signalée comme spam) et l'envoi est impossible",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnprocessableEntityError"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitError"
          },
          "500": {
            "description": "Erreur serveur inattendue. Toute demande de signature partiellement créée est annulée, donc aucun brouillon n'est laissé derrière. Les échecs actionnables côté client lors de l'étape d'envoi renvoient plutôt 400, 402 ou 422.",
            "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": "Récupérer une Demande de Signature",
        "description": "Récupérer une demande de signature spécifique par ID",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Demande de signature récupérée avec succès. Renvoie une structure imbriquée détaillée avec le statut sous forme d'objet et les horodatages regroupés ensemble.",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de débit : 200 requêtes par minute"
              },
              "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": "Mettre à Jour Partiellement une Demande de Signature",
        "description": "Mettre à jour les propriétés de la demande de signature, un seul destinataire, OU un seul champ. Impossible de mettre à jour plusieurs types d'entités dans une même requête. Impossible de mettre à jour après que la demande de signature a été envoyée, terminée ou annulée.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID de la demande de signature"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "object",
                    "description": "Mettre à jour uniquement les propriétés de la demande de signature",
                    "properties": {
                      "name": {
                        "type": "string",
                        "maxLength": 255,
                        "description": "Nouveau nom pour la demande de signature"
                      },
                      "description": {
                        "type": "string",
                        "description": "Nouvelle description"
                      },
                      "document": {
                        "type": "string",
                        "format": "byte",
                        "description": "Remplace le document par un nouveau PDF encodé en base64. Le nombre de pages est extrait automatiquement."
                      },
                      "expiration_hours": {
                        "type": "integer",
                        "minimum": 1,
                        "description": "Nouvelles heures d'expiration"
                      },
                      "settings": {
                        "$ref": "#/components/schemas/SigningRequestSettings",
                        "description": "Mettre à jour les paramètres"
                      }
                    }
                  },
                  {
                    "type": "object",
                    "required": [
                      "recipient"
                    ],
                    "description": "Créer ou mettre à jour un seul destinataire",
                    "properties": {
                      "recipient": {
                        "$ref": "#/components/schemas/Recipient",
                        "description": "Destinataire à créer (omettre id) ou à mettre à jour (inclure id). Lors de la mise à jour de first_name ou last_name, le champ name est automatiquement reconstruit à partir des valeurs existantes en base de données pour tout champ non fourni. Résultat : 'First Last' si les deux existent, 'First' si seul first_name est présent."
                      }
                    }
                  },
                  {
                    "type": "object",
                    "required": [
                      "field"
                    ],
                    "description": "Créer ou mettre à jour un seul champ",
                    "properties": {
                      "field": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid",
                            "description": "Inclure pour mettre à jour un champ existant, omettre pour en créer un nouveau"
                          },
                          "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": "Type de champ. Accepte 'initial' ou 'initials', 'textarea' ou 'text_area'. Requis pour les nouveaux champs. Les champs url sont automatiquement en lecture seule. Les champs file permettent aux signataires de téléverser des pièces jointes (images/PDF). Les champs stamp affichent une image préconfigurée."
                          },
                          "position": {
                            "type": "object",
                            "properties": {
                              "x": {
                                "type": "number",
                                "description": "Position X sur le document"
                              },
                              "y": {
                                "type": "number",
                                "description": "Position Y sur le document"
                              },
                              "width": {
                                "type": "number",
                                "description": "Largeur du champ"
                              },
                              "height": {
                                "type": "number",
                                "description": "Hauteur du champ"
                              }
                            },
                            "description": "Objet position. Toutes les propriétés sont requises pour les nouveaux champs."
                          },
                          "page_number": {
                            "type": "integer",
                            "minimum": 1,
                            "description": "Numéro de page (indexé à partir de 1). Requis pour les nouveaux champs."
                          },
                          "required": {
                            "type": "boolean",
                            "description": "Indique si le champ est requis"
                          },
                          "recipient_id": {
                            "type": "string",
                            "format": "uuid",
                            "nullable": true,
                            "description": "ID du destinataire auquel assigner le champ"
                          },
                          "variable_name": {
                            "type": "string",
                            "description": "Nom de variable pour le mappage des données préremplies"
                          },
                          "variable_defined_name": {
                            "type": "string",
                            "maxLength": 100,
                            "nullable": true,
                            "description": "Nom lisible et personnalisé de la définition du champ. Peut être utilisé comme alternative à variable_name pour cibler des champs lors de la création à partir d'un modèle."
                          },
                          "dropdown_options": {
                            "description": "Options pour les champs de type liste déroulante",
                            "oneOf": [
                              {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              },
                              {
                                "type": "object"
                              }
                            ]
                          },
                          "format_rules": {
                            "type": "object",
                            "description": "Règles de format (ex. format de date, urlDisplayText pour les champs url, acceptedFileTypes pour les champs file)"
                          },
                          "validation_rules": {
                            "type": "object",
                            "description": "Règles de validation pour le champ"
                          },
                          "multi_group_id": {
                            "type": "string",
                            "format": "uuid",
                            "description": "ID de groupe pour les groupes de boutons radio"
                          },
                          "date_default": {
                            "type": "string",
                            "description": "Valeur de date par défaut"
                          },
                          "date_signing_default": {
                            "type": "boolean",
                            "description": "Pour les champs de type date, utiliser la date de signature comme valeur par défaut"
                          },
                          "read_only": {
                            "type": "boolean",
                            "description": "Indique si le champ est en lecture seule (automatiquement vrai pour les champs url)"
                          },
                          "read_only_value": {
                            "type": "string",
                            "description": "Valeur statique pour les champs en lecture seule. Pour les champs url, il s'agit de l'URL vers laquelle pointer le lien."
                          },
                          "final_value": {
                            "type": "string",
                            "description": "Valeur finale du champ (pour les champs préremplis en lecture seule)"
                          }
                        }
                      }
                    }
                  }
                ]
              },
              "examples": {
                "update-properties": {
                  "summary": "Mettre à jour les propriétés",
                  "value": {
                    "name": "Updated Contract Name",
                    "expiration_hours": 72
                  }
                },
                "update-recipient": {
                  "summary": "Mettre à jour un seul destinataire",
                  "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": "Ajouter un nouveau destinataire",
                  "value": {
                    "recipient": {
                      "first_name": "Jane",
                      "last_name": "Doe",
                      "email": "jane@example.com",
                      "designation": "Signer",
                      "order": 2
                    }
                  }
                },
                "create-url-field": {
                  "summary": "Créer un champ 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": "Créer un champ de téléversement de fichier",
                  "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": "Mettre à jour la position d'un champ existant",
                  "value": {
                    "field": {
                      "id": "field123-e89b-12d3-a456-426614174000",
                      "position": {
                        "x": 120,
                        "y": 220
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Demande de signature mise à jour avec succès. La forme de la réponse dépend de ce qui a été mis à jour : une mise à jour des propriétés renvoie {id, name, template_description, document_url, expiration_hours} ; une mise à jour de destinataire renvoie l'objet destinataire complet ; une mise à jour de champ renvoie l'objet champ complet. La réponse peut inclure un champ 'warning' pour les avertissements de validation de format d'email (non bloquant).",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de débit : 120 requêtes par minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "description": "Réponse lors de la mise à jour des propriétés",
                      "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": "Réponse lors de la mise à jour/création d'un destinataire"
                    },
                    {
                      "type": "object",
                      "description": "Réponse lors de la mise à jour/création d'un champ"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide - Impossible de mettre à jour à la fois les propriétés et le destinataire dans la même requête, ou la demande de signature a déjà été envoyée/complétée/annulée",
            "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": "Mise à jour complète de la demande de signature",
        "description": "Effectue des mises à jour complètes d'une demande de signature, y compris les propriétés, les destinataires, les champs et les rappels. Impossible de mettre à jour après que la demande de signature a été envoyée, complétée ou annulée. Toutes les sections sont optionnelles, mais au moins une doit être fournie.\n\n**Modèle d'ID temporaire pour les nouveaux destinataires** : lors de l'ajout de nouveaux destinataires dans une mise à jour complète, utilisez le champ '_temp_id' (format : 'temp_X') au lieu de 'id' pour établir des relations avec les champs et les rappels. Cela permet de créer de nouveaux destinataires et de les référencer dans les champs/rappels en une seule requête. Utilisez le champ 'id' pour mettre à jour des destinataires existants. Règles de validation : (1) les ID temporaires doivent commencer par 'temp_' ; (2) chaque ID temporaire doit être unique au sein de la requête ; (3) les champs et rappels peuvent référencer des ID temporaires dans leur propriété recipient_id ; (4) l'API résout automatiquement les ID temporaires en véritables UUID après la création du destinataire.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID de la demande de signature"
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/UpdateSigningRequestBody"
        },
        "responses": {
          "200": {
            "description": "Demande de signature mise à jour avec succès. Renvoie la demande de signature mise à jour et un résumé des modifications effectuées.",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de débit : 120 requêtes par minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SigningRequestUpdateResponse"
                }
              }
            }
          },
          "400": {
            "description": "Erreurs de validation. Toutes les erreurs de section sont renvoyées ensemble.",
            "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": "Supprimer une demande de signature",
        "description": "Supprime une demande de signature non envoyée (brouillon). Seules les demandes de signature qui n'ont pas été envoyées peuvent être supprimées. Pour les demandes de signature envoyées, utilise plutôt le endpoint d'annulation.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID de la demande de signature"
          }
        ],
        "responses": {
          "200": {
            "description": "Demande de signature supprimée avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de débit : 120 requêtes par minute"
              },
              "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": "Impossible de supprimer une demande de signature qui a été envoyée",
            "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": "Récupérer les utilisateurs d'une demande de signature",
        "description": "Récupère tous les destinataires/utilisateurs d'une demande de signature spécifique",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID de la demande de signature",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Utilisateurs de la demande de signature récupérés avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de débit : 200 requêtes par minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requêtes restantes dans la fenêtre actuelle"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Timestamp Unix de réinitialisation de la limite de débit"
              }
            },
            "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": "PDG",
                      "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": "Récupérer les champs d'une demande de signature",
        "description": "Récupère tous les champs d'une demande de signature spécifique avec leurs valeurs",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID de la demande de signature",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Champs de la demande de signature récupérés avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de débit : 200 requêtes par minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requêtes restantes dans la fenêtre actuelle"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Timestamp Unix de réinitialisation de la limite de débit"
              }
            },
            "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": "Récupérer les rappels d'une demande de signature",
        "description": "Récupère tous les rappels programmés pour une demande de signature spécifique",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID de la demande de signature",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Rappels de la demande de signature récupérés avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de débit : 200 requêtes par minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requêtes restantes dans la fenêtre actuelle"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Timestamp Unix de réinitialisation de la limite de débit"
              }
            },
            "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": "Récupérer la piste d'audit d'une demande de signature",
        "description": "Récupère la piste d'audit complète d'une demande de signature, combinant les actions admin (créée, modifiée, envoyée, annulée) et les actions du signataire (consultée, signée, refusée, téléchargée). Les événements sont triés chronologiquement.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID de la demande de signature"
          }
        ],
        "responses": {
          "200": {
            "description": "Piste d'audit récupérée avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de débit : 120 requêtes par minute"
              },
              "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": "Envoyer une demande de signature",
        "description": "Envoie une demande de signature à tous les destinataires par email. Ceci déclenche l'envoi de l'email et définit le timestamp sent_on.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID de la demande de signature",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Demande de signature envoyée avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de débit : 60 requêtes par minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requêtes restantes dans la fenêtre actuelle"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Timestamp Unix de réinitialisation de la limite de débit"
              }
            },
            "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": "Requête invalide - La demande de signature a déjà été envoyée ou a expiré",
            "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": "Annuler une demande de signature",
        "description": "Annule une demande de signature qui n'a pas encore été complétée. Ne peut annuler que les demandes qui ont été envoyées et qui ne sont pas déjà terminées ou annulées.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID de la demande de signature"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "type": "string",
                    "maxLength": 500,
                    "description": "Raison d'annulation optionnelle"
                  },
                  "notify_signers": {
                    "type": "boolean",
                    "default": true,
                    "description": "Si les signataires doivent être notifiés de l'annulation"
                  }
                }
              },
              "example": {
                "reason": "No longer needed",
                "notify_signers": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Demande de signature annulée avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de débit : 120 requêtes par minute"
              },
              "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": "Impossible d'annuler (déjà annulée, terminée, ou pas encore envoyée)",
            "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": "Renvoyer une demande de signature à des destinataires spécifiques",
        "description": "Renvoie les notifications de la demande de signature à un ou plusieurs destinataires actuellement éligibles pour signer. Pour les demandes avec l'ordre de signature activé, ne peut renvoyer qu'aux destinataires à l'ordre actif actuel. Impossible de renvoyer aux destinataires ayant déjà signé.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID de la demande de signature"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "recipient_ids"
                ],
                "properties": {
                  "recipient_ids": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "description": "Tableau des ID utilisateur des destinataires à qui renvoyer",
                    "minItems": 1
                  },
                  "custom_message": {
                    "type": "string",
                    "maxLength": 1000,
                    "description": "Message personnalisé optionnel à inclure dans la notification de renvoi"
                  }
                }
              },
              "example": {
                "recipient_ids": [
                  "123e4567-e89b-12d3-a456-426614174000"
                ],
                "custom_message": "Gentle reminder to complete your signature"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Demande de signature renvoyée avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de débit : 120 requêtes par minute"
              },
              "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": "Impossible de renvoyer (destinataires ayant déjà signé, ordre de signature invalide, ou demande pas envoyée/annulée/terminée)",
            "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": "Lister les Webhooks",
        "description": "Récupère une liste paginée des webhooks",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            },
            "description": "Numéro de page"
          },
          {
            "name": "page_size",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "description": "Éléments par page"
          },
          {
            "name": "enabled",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "0",
                "1"
              ]
            },
            "description": "Filtrer par statut activé (0=désactivé, 1=activé)"
          },
          {
            "name": "url",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filtrer par URL du webhook (correspondance partielle, insensible à la casse)"
          },
          {
            "name": "event",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filtrer par type d'événement (par ex., 'signing_request.completed')"
          },
          {
            "name": "created_after",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Filtrer les webhooks créés après cette date (format ISO 8601)"
          },
          {
            "name": "created_before",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Filtrer les webhooks créés avant cette date (format ISO 8601)"
          },
          {
            "name": "sort_by",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "url",
                "enabled",
                "created_on",
                "last_changed_on",
                "consecutive_failures"
              ],
              "default": "created_on"
            },
            "description": "Champ selon lequel trier"
          },
          {
            "name": "sort_order",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "Ordre de tri"
          },
          {
            "name": "workspace_id",
            "in": "query",
            "description": "Filtrer les webhooks par espace de travail. Si fourni, ne renvoie que les webhooks limités à cet espace de travail. Si omis, ne renvoie que les webhooks au niveau de l'entreprise.",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Webhooks récupérés avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de débit : 200 requêtes par minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookListResponse"
                }
              }
            }
          },
          "400": {
            "description": "Erreur de validation - format de date ou paramètres de tri invalides",
            "content": {
              "application/json": {
                "examples": {
                  "invalidDate": {
                    "summary": "Format de date invalide",
                    "value": {
                      "error": "Validation failed",
                      "code": "VALIDATION_ERROR",
                      "details": [
                        {
                          "path": [
                            "created_before"
                          ],
                          "message": "created_before must be a valid ISO 8601 date"
                        }
                      ]
                    }
                  },
                  "invalidSort": {
                    "summary": "Paramètre de tri invalide",
                    "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": "Créer un webhook",
        "description": "Créer un nouveau 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 d'espace de travail optionnel. Si fourni, crée un webhook au niveau de l'espace de travail. Si omis, crée un webhook au niveau de l'entreprise."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Webhook créé avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de requêtes : 60 requêtes par minute"
              },
              "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": "Récupérer un webhook",
        "description": "Récupérer un webhook spécifique par ID",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Webhook récupéré avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de requêtes : 200 requêtes par minute"
              },
              "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": "Mettre à jour un webhook",
        "description": "Mettre à jour un webhook existant",
        "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 mis à jour avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de requêtes : 60 requêtes par minute"
              },
              "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": "Supprimer un webhook",
        "description": "Supprimer (soft delete) un webhook par ID. Ça marque le webhook comme supprimé mais conserve les données.",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID du webhook",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Webhook supprimé avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de requêtes : 60 requêtes par minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requêtes restantes dans la fenêtre actuelle"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Timestamp Unix de la réinitialisation de la limite de requêtes"
              }
            },
            "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": "Tester un webhook",
        "description": "Envoyer un payload de test à l'URL du webhook pour vérifier qu'il fonctionne correctement",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID du webhook",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Webhook de test envoyé avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de requêtes : 10 requêtes par minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requêtes restantes dans la fenêtre actuelle"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Timestamp Unix de la réinitialisation de la limite de requêtes"
              }
            },
            "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": "Faire tourner le secret de signature du webhook",
        "description": "Génère un nouveau secret de signature de webhook pour l'entreprise. L'ancien secret reste valide pendant 7 jours pour permettre une migration en douceur. Limité à 1 requête par minute.",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Secret changé avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de requêtes : 1 requête par minute"
              },
              "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": "Limite de requêtes dépassée (1 rotation par minute)",
            "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": "Récupérer le statut de rotation du secret du webhook",
        "description": "Renvoie des infos sur le secret de webhook actuel, incluant le statut de rotation et l'expiration de l'ancien secret le cas échéant.",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Statut du secret récupéré avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de requêtes : 200 requêtes par minute"
              },
              "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": "Aucune configuration de webhook trouvée",
            "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": "Générer un token JWT pour intégrer des modèles",
        "description": "Crée un token JWT pour intégrer un modèle, avec une expiration de 24 heures. C'est l'endpoint standard pour la génération de JWT.\n\n**Remarque** : la fonction autonome `generate-embedded-template-token` est dépréciée au profit de cet endpoint basé sur le routeur.",
        "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 généré avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de requêtes : 120 requêtes par minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requêtes restantes dans la fenêtre actuelle"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Timestamp Unix de la réinitialisation de la limite de requêtes"
              }
            },
            "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": "Révoquer un token JWT de modèle",
        "description": "Révoquer un token JWT généré précédemment, pour l'empêcher d'être utilisé pour l'intégration de modèles. C'est l'endpoint standard pour révoquer les JWT de modèles.",
        "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 révoqué avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de requêtes : 120 requêtes par minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requêtes restantes dans la fenêtre actuelle"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Timestamp Unix de la réinitialisation de la limite de requêtes"
              }
            },
            "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": "Requête invalide - JWT déjà révoqué ou invalide",
            "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": "Générer un token JWT pour une demande de signature",
        "description": "Génère un token JWT pour intégrer un éditeur de demande de signature. Le JWT expire après 7 jours.",
        "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 généré avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de requêtes : 120 requêtes par minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requêtes restantes dans la fenêtre actuelle"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Timestamp Unix de la réinitialisation de la limite de requêtes"
              }
            },
            "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": "Révoquer un token JWT de demande de signature",
        "description": "Révoquer un token JWT généré précédemment pour une demande de signature, pour l'empêcher d'être utilisé pour l'édition intégrée",
        "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 révoqué avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de requêtes : 120 requêtes par minute"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requêtes restantes dans la fenêtre actuelle"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Timestamp Unix de la réinitialisation de la limite de requêtes"
              }
            },
            "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": "Requête invalide - JWT déjà révoqué ou invalide",
            "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": "Lister les modèles d'e-mail de l'espace de travail",
        "description": "Récupérer tous les modèles d'e-mail personnalisés d'un espace de travail",
        "tags": [
          "Email Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID de l'espace de travail"
          }
        ],
        "responses": {
          "200": {
            "description": "Modèles d'e-mail récupérés avec succès",
            "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": "Récupérer un modèle d'e-mail de l'espace de travail",
        "description": "Récupérer un modèle d'e-mail spécifique par type pour un espace de travail",
        "tags": [
          "Email Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID de l'espace de travail"
          },
          {
            "name": "email_type",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "signing_invite",
                "next_signer",
                "signing_expired",
                "signing_cancelled",
                "signing_declined"
              ]
            },
            "description": "Type de modèle d'e-mail"
          }
        ],
        "responses": {
          "200": {
            "description": "Modèle d'e-mail récupéré avec succès",
            "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": "Créer ou mettre à jour un modèle d'e-mail de l'espace de travail",
        "description": "Créer ou mettre à jour un modèle d'e-mail personnalisé pour un type spécifique. Si un modèle existe déjà pour ce type, il sera mis à jour. Un avertissement est renvoyé si le corps du modèle ne contient pas {{signing_link}}.",
        "tags": [
          "Email Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID de l'espace de travail"
          },
          {
            "name": "email_type",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "signing_invite",
                "next_signer",
                "signing_expired",
                "signing_cancelled",
                "signing_declined"
              ]
            },
            "description": "Type de modèle d'e-mail"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "subject",
                  "body"
                ],
                "properties": {
                  "subject": {
                    "type": "string",
                    "maxLength": 500,
                    "description": "Ligne d'objet de l'e-mail"
                  },
                  "body": {
                    "type": "string",
                    "maxLength": 50000,
                    "description": "Corps de l'e-mail (HTML). Utilisez le placeholder {{signing_link}} pour l'URL de signature."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Modèle d'e-mail mis à jour avec succès",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/EmailTemplate"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "warnings": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "201": {
            "description": "Modèle d'email créé avec succès",
            "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": "Supprimer le modèle d'email de l'espace de travail",
        "description": "Supprime un modèle d'email personnalisé. L'espace de travail reviendra à l'utilisation du modèle au niveau de l'entreprise ou du modèle par défaut pour ce type.",
        "tags": [
          "Email Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID de l'espace de travail"
          },
          {
            "name": "email_type",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "signing_invite",
                "next_signer",
                "signing_expired",
                "signing_cancelled",
                "signing_declined"
              ]
            },
            "description": "Type de modèle d'email"
          }
        ],
        "responses": {
          "200": {
            "description": "Modèle d'email supprimé avec succès",
            "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": "Lister les modèles d'email de l'entreprise",
        "description": "Récupère tous les modèles d'email personnalisés au niveau de l'entreprise. Les modèles d'entreprise servent de valeurs par défaut pour tous les espaces de travail qui n'ont pas de modèles spécifiques.",
        "tags": [
          "Email Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Modèles d'email de l'entreprise récupérés avec succès",
            "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": "Créer ou mettre à jour le modèle d'email de l'entreprise",
        "description": "Crée ou met à jour un modèle d'email au niveau de l'entreprise pour un type spécifique. Les modèles d'entreprise sont utilisés comme valeurs par défaut pour les espaces de travail sans modèles spécifiques.",
        "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": "Type de modèle d'email"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "subject",
                  "body"
                ],
                "properties": {
                  "subject": {
                    "type": "string",
                    "maxLength": 500,
                    "description": "Ligne d'objet de l'email"
                  },
                  "body": {
                    "type": "string",
                    "maxLength": 50000,
                    "description": "Corps de l'email (HTML). Utilisez le placeholder {{signing_link}} pour l'URL de signature."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Modèle d'email de l'entreprise mis à jour avec succès",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/EmailTemplate"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "warnings": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "201": {
            "description": "Modèle d'email de l'entreprise créé avec succès",
            "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": "Supprimer le modèle d'email de l'entreprise",
        "description": "Supprime un modèle d'email au niveau de l'entreprise. Les espaces de travail reviendront au modèle par défaut intégré pour ce type.",
        "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": "Type de modèle d'email"
          }
        ],
        "responses": {
          "200": {
            "description": "Modèle d'email de l'entreprise supprimé avec succès",
            "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": "Lister les conditions signataire de l'entreprise",
        "description": "Récupère toutes les conditions signataire au niveau de l'entreprise. Les conditions signataire de l'entreprise servent de valeurs par défaut pour les espaces de travail sans conditions spécifiques.",
        "tags": [
          "Signer Terms"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Conditions signataire de l'entreprise récupérées avec succès",
            "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": "Créer ou mettre à jour les conditions signataire de l'entreprise",
        "description": "Crée ou met à jour les conditions signataire au niveau de l'entreprise pour une langue spécifique. La déclaration soumise est nettoyée avant stockage.",
        "tags": [
          "Signer Terms"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "language",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "es",
                "it",
                "pt",
                "fr",
                "de",
                "el",
                "ru",
                "pl"
              ]
            },
            "description": "Code de langue"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "statement_text"
                ],
                "properties": {
                  "statement_text": {
                    "type": "string",
                    "description": "Déclaration de consentement du signataire au format HTML. Nettoyée avant stockage."
                  },
                  "terms_url": {
                    "type": "string",
                    "format": "uri",
                    "nullable": true,
                    "description": "Lien externe optionnel vers les conditions"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Conditions signataire de l'entreprise mises à jour avec succès",
            "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": "Supprimer les conditions signataire de l'entreprise",
        "description": "Supprime les conditions signataire au niveau de l'entreprise pour une langue spécifique.",
        "tags": [
          "Signer Terms"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "language",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "es",
                "it",
                "pt",
                "fr",
                "de",
                "el",
                "ru",
                "pl"
              ]
            },
            "description": "Code de langue"
          }
        ],
        "responses": {
          "200": {
            "description": "Conditions signataire de l'entreprise supprimées avec succès",
            "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": "Lister les conditions signataire de l'espace de travail",
        "description": "Récupère toutes les conditions signataire personnalisées d'un espace de travail",
        "tags": [
          "Signer Terms"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID de l'espace de travail"
          }
        ],
        "responses": {
          "200": {
            "description": "Conditions signataire de l'espace de travail récupérées avec succès",
            "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": "Créer ou mettre à jour les conditions signataire de l'espace de travail",
        "description": "Crée ou met à jour les conditions signataire au niveau de l'espace de travail pour une langue spécifique. La déclaration soumise est nettoyée avant stockage.",
        "tags": [
          "Signer Terms"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID de l'espace de travail"
          },
          {
            "name": "language",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "es",
                "it",
                "pt",
                "fr",
                "de",
                "el",
                "ru",
                "pl"
              ]
            },
            "description": "Code de langue"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "statement_text"
                ],
                "properties": {
                  "statement_text": {
                    "type": "string",
                    "description": "Déclaration de consentement du signataire au format HTML. Nettoyée avant stockage."
                  },
                  "terms_url": {
                    "type": "string",
                    "format": "uri",
                    "nullable": true,
                    "description": "Lien externe optionnel vers les conditions"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Conditions signataire de l'espace de travail mises à jour avec succès",
            "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": "Supprimer les conditions signataire de l'espace de travail",
        "description": "Supprime les conditions signataire au niveau de l'espace de travail pour une langue spécifique.",
        "tags": [
          "Signer Terms"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID de l'espace de travail"
          },
          {
            "name": "language",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "es",
                "it",
                "pt",
                "fr",
                "de",
                "el",
                "ru",
                "pl"
              ]
            },
            "description": "Code de langue"
          }
        ],
        "responses": {
          "200": {
            "description": "Conditions signataire de l'espace de travail supprimées avec succès",
            "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": "Obtenir les modèles d'email par défaut",
        "description": "Récupère les modèles d'email par défaut intégrés pour une langue spécifique. Ce sont les modèles utilisés lorsqu'aucun modèle d'entreprise ou d'espace de travail personnalisé n'est configuré.",
        "tags": [
          "Email Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "language",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "es",
                "it",
                "pt",
                "fr",
                "de",
                "el",
                "ru",
                "pl"
              ]
            },
            "description": "Code de langue"
          }
        ],
        "responses": {
          "200": {
            "description": "Modèles par défaut récupérés avec succès",
            "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": "Obtenir les placeholders des modèles d'email",
        "description": "Récupère la liste des placeholders disponibles pouvant être utilisés dans les modèles d'email. Les placeholders sont remplacés par les valeurs réelles lors de l'envoi des emails.",
        "tags": [
          "Email Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Placeholders récupérés avec succès",
            "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": "Obtenir les paramètres de l'espace de travail",
        "description": "Récupère les paramètres de l'espace de travail",
        "tags": [
          "Workspace Settings"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paramètres de l'espace de travail récupérés avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de débit : 200 requêtes par minute"
              },
              "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": "Mettre à jour les paramètres de l'espace de travail",
        "description": "Met à jour les paramètres de l'espace de travail",
        "tags": [
          "Workspace Settings"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "signing_request_email_header": {
                    "type": "string"
                  },
                  "signing_request_email_body": {
                    "type": "string"
                  },
                  "team_email": {
                    "type": "string",
                    "format": "email"
                  },
                  "timezone": {
                    "type": "string"
                  },
                  "language": {
                    "type": "string",
                    "enum": [
                      "en",
                      "es",
                      "it",
                      "pt",
                      "fr",
                      "de",
                      "el",
                      "ru",
                      "pl"
                    ],
                    "description": "Langue de l'espace de travail pour les modèles d'email"
                  },
                  "show_credit_cost_in_editor": {
                    "type": "boolean",
                    "description": "Indique s'il faut afficher le coût en crédits dans les éditeurs intégrés"
                  },
                  "require_otp_verification": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "Indique si les signataires doivent vérifier leur email via OTP. null = hérite de l'entreprise"
                  },
                  "require_terms_acceptance": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "Indique si les signataires doivent accepter les conditions avant de signer. null hérite du paramètre au niveau de l'entreprise."
                  },
                  "disable_guided_navigation": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "Désactive le défilement automatique vers le prochain champ requis pendant la signature. Hérite de l'espace de travail ou de l'entreprise si non défini."
                  },
                  "show_signature_frame": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "Indique s'il faut afficher les cadres de signature dans les PDF terminés. null = hérite de l'entreprise"
                  },
                  "color_primary": {
                    "type": "string",
                    "nullable": true,
                    "description": "Remplacement de la couleur principale (hex #rrggbb). Null pour hériter de l'entreprise."
                  },
                  "color_primary_fg": {
                    "type": "string",
                    "nullable": true,
                    "description": "Surcharge de la couleur de premier plan principale. Null pour hériter de l'entreprise."
                  },
                  "color_background": {
                    "type": "string",
                    "nullable": true,
                    "description": "Surcharge de la couleur d'arrière-plan. Null pour hériter de l'entreprise."
                  },
                  "color_foreground": {
                    "type": "string",
                    "nullable": true,
                    "description": "Surcharge de la couleur de premier plan/texte. Null pour hériter de l'entreprise."
                  },
                  "color_card": {
                    "type": "string",
                    "nullable": true,
                    "description": "Surcharge de la couleur d'arrière-plan des cartes. Null pour hériter de l'entreprise."
                  },
                  "color_border": {
                    "type": "string",
                    "nullable": true,
                    "description": "Surcharge de la couleur de bordure. Null pour hériter de l'entreprise."
                  },
                  "color_accent": {
                    "type": "string",
                    "nullable": true,
                    "description": "Couleur d'accent de l'interface de l'éditeur. Null pour hériter de l'entreprise."
                  },
                  "color_accent_fg": {
                    "type": "string",
                    "nullable": true,
                    "description": "Couleur de premier plan sur les surfaces d'accent. Null pour hériter de l'entreprise."
                  },
                  "color_canvas": {
                    "type": "string",
                    "nullable": true,
                    "description": "Couleur du pourtour du canevas de document dans l'éditeur. Null pour hériter de l'entreprise."
                  },
                  "color_muted": {
                    "type": "string",
                    "nullable": true,
                    "description": "Couleur de surface atténuée. Null pour hériter de l'entreprise."
                  },
                  "color_muted_fg": {
                    "type": "string",
                    "nullable": true,
                    "description": "Couleur de texte atténuée. Null pour hériter de l'entreprise."
                  },
                  "email_local_part": {
                    "type": "string",
                    "nullable": true,
                    "description": "La partie locale (avant le @) de l'adresse email de l'expéditeur. Null pour hériter du paramètre de l'entreprise.",
                    "pattern": "^[a-z0-9]([a-z0-9._-]*[a-z0-9])?$",
                    "minLength": 1,
                    "maxLength": 64
                  },
                  "allow_presigning_download": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "Autoriser les signataires à télécharger le document original avant de signer. Hérite du paramètre de l'espace de travail ou de l'entreprise quand null."
                  },
                  "show_partial_watermark": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "Afficher un filigrane EN COURS sur les téléchargements PDF partiels lorsque tous les signataires n'ont pas terminé. null hérite du paramètre au niveau de l'entreprise."
                  },
                  "show_qr_code": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "Afficher un code QR sur la page de signature permettant aux signataires de continuer sur leur téléphone. Hérite du paramètre de l'espace de travail ou de l'entreprise quand null."
                  },
                  "signing_button_label_overrides": {
                    "type": "object",
                    "nullable": true,
                    "description": "Libellés de boutons personnalisés par langue pour la vue de signature. Les clés sont des codes de langue (en, de, etc.) ; les valeurs sont des objets associant des clés de traduction à un texte personnalisé. Null pour utiliser les valeurs par défaut.",
                    "additionalProperties": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Paramètres de l'espace de travail mis à jour avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de débit : 120 requêtes par minute"
              },
              "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": "Lister les domaines de l'espace de travail",
        "description": "Lister tous les domaines email configurés pour un espace de travail spécifique. Ces domaines sont utilisés pour envoyer les emails de demande de signature depuis cet espace de travail.",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID de l'espace de travail"
          }
        ],
        "responses": {
          "200": {
            "description": "Domaines de l'espace de travail récupérés avec succès",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de débit : 200 requêtes par minute"
              },
              "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": "Ajouter un domaine à l'espace de travail",
        "description": "Ajouter un nouveau domaine email pour un espace de travail spécifique. Cela lance le processus de vérification du domaine. Après la création, vous devez :\n1. Ajouter un enregistrement TXT à votre DNS avec le jeton de vérification\n2. Appeler POST /workspace/{workspace_id}/domains/{id}/verify-ownership pour vérifier la propriété du domaine\n3. Appeler POST /workspace/{workspace_id}/domains/{id}/finalize pour l'enregistrer auprès du fournisseur d'email\n4. Ajouter les enregistrements DNS retournés (SPF, DKIM, etc.)\n5. Appeler POST /workspace/{workspace_id}/domains/{id}/verify-dns pour terminer la vérification",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID de l'espace de travail"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "domain"
                ],
                "properties": {
                  "domain": {
                    "type": "string",
                    "description": "Nom de domaine à ajouter (par ex., 'example.com'). Doit être un format de domaine valide.",
                    "example": "sales.acme.com"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Domaine créé avec succès. Ajoutez l'enregistrement TXT de vérification à votre DNS.",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de débit : 120 requêtes par minute"
              },
              "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": "Format de domaine invalide ou domaine déjà existant",
            "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": "Récupérer un domaine de l'espace de travail",
        "description": "Récupérer les détails d'un domaine spécifique dans un espace de travail, y compris le statut de vérification et les enregistrements DNS",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID de l'espace de travail"
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID du domaine"
          }
        ],
        "responses": {
          "200": {
            "description": "Domaine récupéré avec succès",
            "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": "Supprimer un domaine de l'espace de travail",
        "description": "Supprimer un domaine de l'espace de travail. Si le domaine est le domaine principal ou unique, l'envoi revient à l'expéditeur de l'entreprise ou par défaut.",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID de l'espace de travail"
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID du domaine"
          }
        ],
        "responses": {
          "200": {
            "description": "Domaine supprimé avec succès",
            "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": "Vérifier la propriété d'un domaine de l'espace de travail",
        "description": "Vérifier la propriété du domaine en contrôlant l'enregistrement TXT. Appelez ceci après avoir ajouté l'enregistrement TXT de vérification à votre DNS. La propagation DNS peut prendre jusqu'à 48 heures, mais se termine généralement en quelques minutes.",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID de l'espace de travail"
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID du domaine"
          }
        ],
        "responses": {
          "200": {
            "description": "Propriété du domaine vérifiée avec succès",
            "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": "Échec de la vérification",
            "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": "Finaliser la configuration du domaine de l'espace de travail",
        "description": "Finaliser la configuration du domaine en l'enregistrant auprès du fournisseur d'email. Cela retourne les enregistrements DNS (SPF, DKIM, DMARC) qui doivent être ajoutés pour activer l'envoi d'emails. Ne peut être appelé qu'après vérification de la propriété du domaine.",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID de l'espace de travail"
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID du domaine"
          }
        ],
        "responses": {
          "200": {
            "description": "Domaine finalisé avec succès. Ajoutez les enregistrements DNS retournés.",
            "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": "Impossible de finaliser",
            "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": "Vérifier les enregistrements DNS du domaine de l'espace de travail",
        "description": "Vérifie que tous les enregistrements DNS requis (SPF, DKIM, DMARC) sont correctement configurés. Appelle ce endpoint après avoir ajouté tous les enregistrements DNS depuis l'étape de finalisation. Une fois vérifié, le domaine est prêt pour l'envoi d'e-mails.",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID de l'espace de travail"
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID du domaine"
          }
        ],
        "responses": {
          "200": {
            "description": "Résultat de la vérification DNS",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DomainVerifyDnsResponse"
                },
                "examples": {
                  "verified": {
                    "summary": "Tous les enregistrements sont vérifiés",
                    "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": "Certains enregistrements sont en attente",
                    "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": "Domaine non finalisé",
            "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": "Définir le domaine principal de l'espace de travail",
        "description": "Définit un domaine comme domaine d'envoi principal pour l'espace de travail. Seuls les domaines entièrement vérifiés (domain_status=1) peuvent être définis comme principaux.",
        "tags": [
          "Email Domains"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID de l'espace de travail"
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID du domaine"
          }
        ],
        "responses": {
          "200": {
            "description": "Domaine principal mis à jour avec succès",
            "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": "Domaine non vérifié",
            "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": "Lister les champs personnalisés de l'espace de travail",
        "description": "Récupère toutes les définitions de champs personnalisés pour un espace de travail",
        "tags": [
          "Custom Fields"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "description": "ID de l'espace de travail",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Champs personnalisés récupérés avec succès",
            "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": "Créer un champ personnalisé pour l'espace de travail",
        "description": "Crée une nouvelle définition de champ personnalisé pour un espace de travail",
        "tags": [
          "Custom Fields"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "path",
            "required": true,
            "description": "ID de l'espace de travail",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "field_label"
                ],
                "properties": {
                  "field_label": {
                    "type": "string",
                    "description": "Libellé d'affichage (1 à 100 caractères)",
                    "maxLength": 100
                  },
                  "field_name": {
                    "type": "string",
                    "description": "Nom lisible par machine facultatif (généré automatiquement à partir du libellé si non fourni)",
                    "maxLength": 50
                  },
                  "is_preset": {
                    "type": "boolean",
                    "description": "Si vrai, le champ a une valeur prédéfinie pour tous les utilisateurs",
                    "default": false
                  },
                  "preset_value": {
                    "type": "string",
                    "description": "Valeur prédéfinie (500 caractères max, utilisée uniquement quand is_preset=true)",
                    "maxLength": 500
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Champ personnalisé créé avec succès",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkspaceCustomField"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/UnauthorizedError"
          },
          "409": {
            "description": "Conflit - Un champ personnalisé avec ce nom existe déjà",
            "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": "Mettre à jour un champ personnalisé de l'espace de travail",
        "description": "Met à jour une définition de champ personnalisé existante",
        "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": "Champ personnalisé mis à jour avec succès",
            "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": "Conflit - Un champ personnalisé avec ce nom existe déjà",
            "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": "Supprimer un champ personnalisé de l'espace de travail",
        "description": "Supprime (suppression douce) une définition de champ personnalisé",
        "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": "Champ personnalisé supprimé avec succès",
            "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": "Lister les champs personnalisés du modèle",
        "description": "Récupère toutes les définitions de champs personnalisés pour un modèle",
        "tags": [
          "Custom Fields"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "template_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Champs personnalisés récupérés avec succès",
            "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": "Créer un champ personnalisé pour le modèle",
        "description": "Crée une nouvelle définition de champ personnalisé pour un modèle",
        "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": "Champ personnalisé créé avec succès",
            "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": "Conflit - Un champ personnalisé avec ce nom existe déjà",
            "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": "Supprimer un champ personnalisé du modèle",
        "description": "Supprime (suppression douce) une définition de champ personnalisé d'un modèle",
        "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": "Champ personnalisé supprimé avec succès",
            "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": "Lister les champs personnalisés de la demande de signature",
        "description": "Récupère toutes les définitions de champs personnalisés pour une demande de signature",
        "tags": [
          "Custom Fields"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "request_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Champs personnalisés récupérés avec succès",
            "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": "Créer un champ personnalisé pour la demande de signature",
        "description": "Crée une nouvelle définition de champ personnalisé pour une demande de signature",
        "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": "Champ personnalisé créé avec succès",
            "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": "Conflit - Un champ personnalisé avec ce nom existe déjà",
            "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": "Supprimer un champ personnalisé de la demande de signature",
        "description": "Supprime (suppression douce) une définition de champ personnalisé d'une demande de signature",
        "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": "Champ personnalisé supprimé avec succès",
            "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": "Faire tourner le secret webhook de l'espace de travail",
        "description": "Génère un nouveau secret de signature webhook pour l'espace de travail. L'ancien secret reste valide pendant 7 jours.",
        "operationId": "rotateWorkspaceWebhookSecret",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID de l'espace de travail",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Secret changé avec succès",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RotateSecretResponse"
                }
              }
            }
          },
          "429": {
            "description": "Période de blocage active — le secret a été changé récemment"
          }
        },
        "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": "Récupérer le statut du secret webhook de l'espace de travail",
        "description": "Retourne le statut du secret webhook de l'espace de travail, incluant la date de création, la date de rotation et le statut de la période de grâce.",
        "operationId": "getWorkspaceWebhookSecretStatus",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID de l'espace de travail",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Statut du secret récupéré",
            "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": "Télécharger le document de la demande de signature",
        "description": "Récupère une URL de téléchargement pour le document signé d'une demande de signature. Pour les demandes de signature terminées, retourne le PDF final signé. Pour les demandes de signature en cours où le téléchargement partiel est activé, retourne une URL vers le document partiellement signé généré au moment de la dernière signature effectuée.\n\n**Téléchargements partiels :** Les téléchargements partiels sont disponibles uniquement lorsque `allow_partial_download` est activé dans les paramètres de la demande de signature. Si le document n'a pas encore été généré partiellement, un `503` est retourné — réessaie après l'intervalle indiqué dans `Retry-After`.\n\n**Expiration de l'URL :** `download_url` est une URL pré-signée qui expire. L'horodatage d'expiration est fourni dans `expires_at`.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID de la demande de signature",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "URL de téléchargement récupérée avec succès.",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Limite de débit : 200 requêtes par minute"
              },
              "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": "Demande de signature introuvable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "not_found"
                }
              }
            }
          },
          "409": {
            "description": "La demande de signature n'a pas encore été envoyée. Le téléchargement est disponible uniquement après l'envoi de la demande.",
            "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 génération du document est en cours. Réessayez après l'intervalle indiqué.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Secondes à attendre avant de réessayer"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "generation_timeout": {
                    "summary": "La génération du document a expiré",
                    "value": {
                      "error": "generation_timeout"
                    }
                  },
                  "stale_at_publication": {
                    "summary": "Le document était obsolète au moment de la publication",
                    "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": "Récupérer l'Image de Signature du Signataire",
        "description": "Récupère la signature adoptée d'un signataire sous forme d'URI de données PNG en base64, séparément du PDF signé. Un signataire adopte une seule signature appliquée à tous ses champs de signature, donc aucun field_id n'est nécessaire. Les signatures dessinées renvoient l'image capturée ; les signatures tapées sont rendues en PNG côté serveur. `image` est une URI `data:image/png;base64,...` utilisable directement dans un `<img src>`. Par défaut, un cadre d'identification du signataire est superposé (`include_frame=false` pour l'omettre). Chaque récupération réussie est enregistrée dans un journal d'audit. Limité à 60/min. La validité juridique repose sur le PDF scellé et le certificat d'achèvement, pas sur cette image.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID de la demande de signature",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "signer_id",
            "in": "path",
            "required": true,
            "description": "ID du signataire (destinataire) — le recipient_id de GET /fields",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "include_frame",
            "in": "query",
            "required": false,
            "description": "Superposer le cadre d'identification du signataire sur l'image (true par défaut). Réglez sur false pour la marque brute.",
            "schema": {
              "type": "boolean",
              "default": true
            }
          }
        ],
        "responses": {
          "200": {
            "description": "La marque du signataire sous forme d'URI de données PNG en 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": "Indique si le cadre d'identification du signataire a été superposé."
                    },
                    "image": {
                      "type": "string",
                      "description": "PNG sous forme d'URI de données.",
                      "example": "data:image/png;base64,iVBORw0KGgo..."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Clé API manquante ou invalide.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Demande de signature/signataire/champ introuvable ou n'appartenant pas à votre espace de travail (NOT_FOUND), ou aucune marque capturée (SIGNATURE_NOT_AVAILABLE).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Limite de débit dépassée (60/min pour la récupération de signature).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Le rendu a échoué (RENDER_FAILED) ou l'écriture obligatoire du journal d'audit d'accès a échoué (AUDIT_WRITE_FAILED) ; aucune image n'est renvoyée.",
            "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": "Récupérer l'Image des Initiales du Signataire",
        "description": "Récupère les initiales adoptées d'un signataire sous forme d'URI de données PNG en base64. Une seule marque d'initiales par signataire (pas de field_id). Même forme de réponse, cadre, audit et limite de débit que le point de terminaison de signature.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID de la demande de signature",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "signer_id",
            "in": "path",
            "required": true,
            "description": "ID du signataire (destinataire)",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "include_frame",
            "in": "query",
            "required": false,
            "description": "Superposer le cadre d'identification du signataire sur l'image (true par défaut). Réglez sur false pour la marque brute.",
            "schema": {
              "type": "boolean",
              "default": true
            }
          }
        ],
        "responses": {
          "200": {
            "description": "La marque du signataire sous forme d'URI de données PNG en 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": "Indique si le cadre d'identification du signataire a été superposé."
                    },
                    "image": {
                      "type": "string",
                      "description": "PNG sous forme d'URI de données.",
                      "example": "data:image/png;base64,iVBORw0KGgo..."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Clé API manquante ou invalide.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Demande de signature/signataire/champ introuvable ou n'appartenant pas à votre espace de travail (NOT_FOUND), ou aucune marque capturée (SIGNATURE_NOT_AVAILABLE).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Limite de débit dépassée (60/min pour la récupération de signature).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Le rendu a échoué (RENDER_FAILED) ou l'écriture obligatoire du journal d'audit d'accès a échoué (AUDIT_WRITE_FAILED) ; aucune image n'est renvoyée.",
            "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": "Récupérer l'Image du Tampon du Signataire",
        "description": "Récupère le tampon d'un signataire pour un champ de tampon spécifique sous forme d'URI de données PNG en base64. Les tampons sont par champ, donc `field_id` est requis (obtenez-le via GET /signing-requests/{id}/fields, en filtrant sur type=stamp). Même cadre, audit et limite de 60/min.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID de la demande de signature",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "signer_id",
            "in": "path",
            "required": true,
            "description": "ID du signataire (destinataire)",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "field_id",
            "in": "path",
            "required": true,
            "description": "ID du champ de tampon",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "include_frame",
            "in": "query",
            "required": false,
            "description": "Superposer le cadre d'identification du signataire sur l'image (true par défaut). Réglez sur false pour la marque brute.",
            "schema": {
              "type": "boolean",
              "default": true
            }
          }
        ],
        "responses": {
          "200": {
            "description": "La marque du signataire sous forme d'URI de données PNG en 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": "Indique si le cadre d'identification du signataire a été superposé."
                    },
                    "image": {
                      "type": "string",
                      "description": "PNG sous forme d'URI de données.",
                      "example": "data:image/png;base64,iVBORw0KGgo..."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Le champ n'est pas du type attendu (INVALID_FIELD_TYPE).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Clé API manquante ou invalide.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Demande de signature/signataire/champ introuvable ou n'appartenant pas à votre espace de travail (NOT_FOUND), ou aucune marque capturée (SIGNATURE_NOT_AVAILABLE).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Limite de débit dépassée (60/min pour la récupération de signature).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Le rendu a échoué (RENDER_FAILED) ou l'écriture obligatoire du journal d'audit d'accès a échoué (AUDIT_WRITE_FAILED) ; aucune image n'est renvoyée.",
            "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": "Récupérer un Fichier Téléversé par le Signataire",
        "description": "Récupère un fichier qu'un signataire a téléversé dans un champ de fichier. Renvoie une URL de téléchargement pré-signée de courte durée (300s), pas les octets. `field_id` est requis (via GET /signing-requests/{id}/fields, en filtrant sur type=file). Chaque récupération est enregistrée dans un journal d'audit ; limite de 60/min. Téléchargez rapidement côté serveur avant l'expiration de l'URL.",
        "tags": [
          "Signing Requests"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID de la demande de signature",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "signer_id",
            "in": "path",
            "required": true,
            "description": "ID du signataire (destinataire)",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "field_id",
            "in": "path",
            "required": true,
            "description": "ID du champ de fichier",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Une URL pré-signée de courte durée pour le fichier téléversé par le signataire.",
            "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 téléchargement pré-signée."
                    },
                    "expires_in": {
                      "type": "integer",
                      "example": 300,
                      "description": "Secondes avant l'expiration de l'URL."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Le champ n'est pas un champ fichier (INVALID_FIELD_TYPE).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Clé API manquante ou invalide.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Non trouvé / pas dans ton espace de travail (NOT_FOUND) ou aucun fichier téléversé (SIGNATURE_NOT_AVAILABLE).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Limite de taux dépassée (60/min).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "La génération de l'URL signée a échoué (INTERNAL_ERROR) ou l'écriture obligatoire de l'audit d'accès a échoué (AUDIT_WRITE_FAILED) ; aucune URL n'est retournée.",
            "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": "Téléverser le logo de l'entreprise",
        "description": "Téléverse une image de logo pour l'entreprise. Accepte PNG ou JPEG, 2 Mo maximum. Remplace le logo existant, s'il y en a un.",
        "operationId": "uploadCompanyLogo",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "Fichier image du logo (PNG ou JPEG, 2 Mo maximum)"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Logo téléversé avec succès",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LogoUploadResponse"
                }
              }
            }
          },
          "400": {
            "description": "Fichier invalide (mauvais format, trop volumineux, ou manquant)"
          }
        },
        "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": "Supprimer le logo de l'entreprise",
        "description": "Supprime le logo de l'entreprise. Les certificats utiliseront le logo par défaut de Firma.",
        "operationId": "deleteCompanyLogo",
        "responses": {
          "200": {
            "description": "Logo supprimé avec succès",
            "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": "Téléverser le logo de l'espace de travail",
        "description": "Téléverse un logo pour un espace de travail spécifique. Remplace le logo de l'entreprise sur les certificats et les e-mails pour cet espace de travail. Accepte PNG ou JPEG, 2 Mo maximum.",
        "operationId": "uploadWorkspaceLogo",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID de l'espace de travail"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "Fichier image du logo (PNG ou JPEG, 2 Mo maximum)"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Logo téléversé avec succès",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LogoUploadResponse"
                }
              }
            }
          },
          "400": {
            "description": "Fichier invalide (mauvais format, trop volumineux, ou manquant)"
          }
        },
        "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": "Supprimer le logo de l'espace de travail",
        "description": "Supprime le logo de l'espace de travail. Les certificats utiliseront alors le logo de l'entreprise, ou celui par défaut de Firma.",
        "operationId": "deleteWorkspaceLogo",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID de l'espace de travail"
          }
        ],
        "responses": {
          "200": {
            "description": "Logo supprimé avec succès",
            "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": "Téléverser un document",
        "description": "Demande une URL de téléversement préautorisée pour un document. Téléverse le fichier directement vers l'URL retournée, puis passe le document_id lors de la création d'une demande de signature. Utilise ceci pour les documents de plus de 5 Mo qui dépassent la limite de taille des requêtes en base64 inline.",
        "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": "Nom du fichier du document",
                    "example": "contract.pdf"
                  },
                  "file_size": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 52428800,
                    "description": "Taille du fichier en octets. Maximum 50 Mo (52 428 800 octets).",
                    "example": 15000000
                  },
                  "content_type": {
                    "type": "string",
                    "enum": [
                      "application/pdf",
                      "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
                    ],
                    "description": "Type MIME du document",
                    "example": "application/pdf"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "URL de téléversement créée",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "document_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "ID du document à passer dans la demande de signature"
                    },
                    "upload_url": {
                      "type": "string",
                      "format": "uri",
                      "description": "URL préautorisée sur laquelle faire un PUT du fichier du document. Envoie les octets bruts du fichier avec un Content-Type correspondant au content_type demandé."
                    },
                    "upload_token": {
                      "type": "string",
                      "description": "Jeton d'authentification du téléversement (inclus dans l'upload_url)"
                    },
                    "expires_in": {
                      "type": "integer",
                      "description": "Secondes avant l'expiration de l'URL de téléversement",
                      "example": 3600
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Erreur de validation (file_size, content_type invalides, etc.)"
          },
          "401": {
            "description": "Clé API invalide ou manquante"
          }
        },
        "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);"
          }
        ]
      }
    }
  }
}
