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

# ChatGPT

> Ajoutez des signatures électroniques juridiquement contraignantes à toute application basée sur ChatGPT grâce au function calling, à la CLI Codex ou aux connecteurs ChatGPT.

Firma vous permet d'ajouter des signatures électroniques juridiquement contraignantes à tout ce que vous construisez sur OpenAI. Utilisez le function calling de la Responses API pour permettre à vos agents IA d'envoyer des demandes de signature à la demande, connectez les serveurs MCP de Firma à la CLI Codex pour que l'IA génère du code d'intégration précis, ou ajoutez Firma comme connecteur ChatGPT pour gérer vos demandes de signature depuis l'application de bureau ChatGPT.

## Prérequis

* Un [compte Firma](https://app.firma.dev) avec une clé API
* Une clé API OpenAI (pour le function calling), ou un compte ChatGPT Plus/Pro/Enterprise (pour la CLI Codex et les connecteurs)
* Au moins un Modèle Firma avec des Champs de signature configurés

<Note>
  Firma utilise la clé API brute comme valeur de l'en-tête `Authorization` - ne la préfixez pas avec `Bearer`. Cela diffère de l'API OpenAI elle-même, qui utilise des jetons `Bearer`.
</Note>

## Pour commencer

<Tabs>
  <Tab title="Function calling">
    Le function calling permet à un modèle GPT de décider quand appeler votre code. Vous déclarez une fonction que le modèle peut appeler, et lorsque l'utilisateur lui demande d'envoyer un contrat, le modèle renvoie un appel d'outil structuré que votre application exécute contre l'API Firma.

    Cette approche convient parfaitement aux agents IA, chatbots, et à toute application où une demande utilisateur en langage naturel doit se transformer en Demande de Signature.

    ### Étape 1 : Stockez vos clés API

    Conservez votre clé API OpenAI et votre clé API Firma dans des variables d'environnement. Ne les placez jamais dans du code frontend.

    ```bash theme={null}
    OPENAI_API_KEY=your_openai_key
    FIRMA_API_KEY=your_firma_key
    ```

    ### Étape 2 : Déclarez une fonction et gérez les appels d'outils

    Avec la Responses API d'OpenAI (recommandée pour les nouveaux projets) :

    ```javascript theme={null}
    import OpenAI from "openai";

    const FIRMA_API = "https://api.firma.dev/functions/v1/signing-request-api";
    const openai = new OpenAI();

    const tools = [
      {
        type: "function",
        name: "send_signing_request",
        description:
          "Send a document for e-signature via Firma. Uses a pre-configured template and one signer.",
        parameters: {
          type: "object",
          properties: {
            name: {
              type: "string",
              description: "A descriptive name for the signing request.",
            },
            template_id: {
              type: "string",
              description: "The ID of the Firma template to send.",
            },
            signer_email: { type: "string" },
            signer_first_name: { type: "string" },
            signer_last_name: { type: "string" },
          },
          required: [
            "name",
            "template_id",
            "signer_email",
            "signer_first_name",
            "signer_last_name",
          ],
          additionalProperties: false,
        },
        strict: true,
      },
    ];

    async function sendSigningRequest(args) {
      const response = await fetch(
        `${FIRMA_API}/signing-requests/create-and-send`,
        {
          method: "POST",
          headers: {
            Authorization: process.env.FIRMA_API_KEY,
            "Content-Type": "application/json",
          },
          body: JSON.stringify({
            name: args.name,
            template_id: args.template_id,
            recipients: [
              {
                first_name: args.signer_first_name,
                last_name: args.signer_last_name,
                email: args.signer_email,
                designation: "Signer",
                order: 1,
              },
            ],
          }),
        }
      );

      const data = await response.json();
      if (!response.ok) return JSON.stringify({ error: data });

      return JSON.stringify({
        signing_request_id: data.id,
        status: "sent",
        signing_link: data.first_signer?.signing_link,
      });
    }

    export async function handleUserMessage(userText) {
      let input = [{ role: "user", content: userText }];

      let response = await openai.responses.create({
        model: "gpt-4.1",
        tools,
        input,
      });

      input.push(...response.output);

      for (const item of response.output) {
        if (item.type !== "function_call") continue;
        if (item.name === "send_signing_request") {
          const args = JSON.parse(item.arguments);
          const result = await sendSigningRequest(args);
          input.push({
            type: "function_call_output",
            call_id: item.call_id,
            output: result,
          });
        }
      }

      response = await openai.responses.create({
        model: "gpt-4.1",
        tools,
        input,
      });

      return { text: response.output_text };
    }
    ```

    <Note>
      Le endpoint `create-and-send` crée la Demande de Signature et l'envoie aux Destinataires en un seul appel API. Si vous voulez que le modèle rédige une demande pour révision avant l'envoi, utilisez `POST /signing-requests` pour créer un brouillon, puis `POST /signing-requests/{id}/send` une fois approuvé.
    </Note>

    ### Étape 3 : Intégrez-le dans votre application

    Appelez `handleUserMessage` depuis votre backend chaque fois que l'utilisateur envoie un message de chat :

    ```javascript theme={null}
    app.post("/chat", async (req, res) => {
      const reply = await handleUserMessage(req.body.message);
      res.json(reply);
    });
    ```

    Un message utilisateur comme « Envoie le contrat de conseil à [alice@acme.com](mailto:alice@acme.com) » déclenchera l'appel de fonction.

    ### Alternative Python

    Le même flux avec le SDK Python :

    ```python theme={null}
    import os
    import json
    import requests
    from openai import OpenAI

    FIRMA_API = "https://api.firma.dev/functions/v1/signing-request-api"
    client = OpenAI()

    tools = [
        {
            "type": "function",
            "name": "send_signing_request",
            "description": "Send a document for e-signature via Firma.",
            "parameters": {
                "type": "object",
                "properties": {
                    "name": {"type": "string", "description": "A descriptive name for the signing request."},
                    "template_id": {"type": "string"},
                    "signer_email": {"type": "string"},
                    "signer_first_name": {"type": "string"},
                    "signer_last_name": {"type": "string"},
                },
                "required": [
                    "name",
                    "template_id",
                    "signer_email",
                    "signer_first_name",
                    "signer_last_name",
                ],
                "additionalProperties": False,
            },
            "strict": True,
        },
    ]

    def execute(args):
        r = requests.post(
            f"{FIRMA_API}/signing-requests/create-and-send",
            headers={
                "Authorization": os.environ["FIRMA_API_KEY"],
                "Content-Type": "application/json",
            },
            json={
                "name": args["name"],
                "template_id": args["template_id"],
                "recipients": [
                    {
                        "first_name": args["signer_first_name"],
                        "last_name": args["signer_last_name"],
                        "email": args["signer_email"],
                        "designation": "Signer",
                        "order": 1,
                    }
                ],
            },
        )
        return json.dumps(r.json())

    input_list = [{"role": "user", "content": "Send the NDA to bob@example.com (Bob Smith)."}]

    response = client.responses.create(
        model="gpt-4.1",
        tools=tools,
        input=input_list,
    )

    input_list += response.output

    for item in response.output:
        if item.type == "function_call":
            args = json.loads(item.arguments)
            result = execute(args)
            input_list.append({
                "type": "function_call_output",
                "call_id": item.call_id,
                "output": result,
            })

    response = client.responses.create(
        model="gpt-4.1",
        tools=tools,
        input=input_list,
    )
    print(response.output_text)
    ```
  </Tab>

  <Tab title="Codex CLI via MCP">
    La CLI Codex d'OpenAI est un agent de codage en ligne de commande qui prend en charge les serveurs MCP. Connecter les serveurs MCP de Firma permet à l'agent de créer des intégrations Firma et d'opérer sur vos données Firma.

    ### Étape 1 : Installez la CLI Codex

    ```bash theme={null}
    npm i -g @openai/codex
    ```

    Ou via Homebrew :

    ```bash theme={null}
    brew install codex
    ```

    ### Étape 2 : Ajoutez les serveurs MCP Firma

    Modifiez votre configuration globale dans `~/.codex/config.toml`, ou créez un fichier `.codex/config.toml` propre au projet :

    ```toml theme={null}
    [mcp_servers.firma-api]
    url = "https://mcp.firma.dev/mcp"

    [mcp_servers.firma-docs]
    url = "https://docs.firma.dev/mcp"
    ```

    Ou ajoutez-les via la CLI :

    ```bash theme={null}
    codex mcp add firma-api --url https://mcp.firma.dev/mcp
    codex mcp add firma-docs --url https://docs.firma.dev/mcp
    ```

    Lors de la première utilisation d'un outil de l'API Firma, la CLI Codex vous guidera pour vous connecter via OAuth.

    <Note>
      Quel serveur utiliser : `firma-api` sert à faire des choses (envoyer des Demandes de Signature, gérer les Modèles). `firma-docs` sert à construire des choses (générer du code d'intégration avec des détails d'API précis). La plupart des développeurs voudront connecter les deux.
    </Note>

    ### Étape 3 : Utilisez Firma depuis la CLI Codex

    Une fois connecté, demandez à la CLI Codex de créer des intégrations ou d'opérer sur vos données :

    ```text theme={null}
    Using the Firma API docs, create an Express route that:
    1. Accepts a name, template_id, signer email, and signer name
    2. Uses the create-and-send endpoint to send a signing request
    3. Returns the signing request ID and the signer's signing link
    Store the API key in process.env.FIRMA_API_KEY.
    ```

    Le fait de mentionner explicitement « les docs Firma » indique à l'agent d'interroger le serveur MCP `firma-docs` avant d'écrire du code.
  </Tab>

  <Tab title="Connecteurs ChatGPT">
    L'application de bureau ChatGPT prend en charge les serveurs MCP via des connecteurs. Cela vous permet de gérer les Demandes de Signature, Modèles et Espaces de Travail Firma directement depuis l'interface de chat ChatGPT.

    ### Étape 1 : Activez le Mode Développeur

    Ouvrez les paramètres de ChatGPT et accédez à **Paramètres > Connectors > Advanced > Developer Mode**. Le Mode Développeur est disponible sur les forfaits Plus, Pro, Business, Enterprise et Education.

    ### Étape 2 : Ajoutez les serveurs MCP Firma

    Cliquez sur **Add custom connector** et ajoutez :

    * **Firma API** - URL : `https://mcp.firma.dev/mcp`
    * **Firma Docs** - URL : `https://docs.firma.dev/mcp`

    Lors de la première connexion au serveur de l'API Firma, vous serez invité à vous authentifier avec votre compte Firma via OAuth.

    ### Étape 3 : Utilisez Firma depuis ChatGPT

    Une fois les connecteurs actifs, vous pouvez demander à ChatGPT de gérer votre compte Firma :

    * « Liste tous mes Modèles Firma »
    * « Envoie le Modèle NDA à [alice@example.com](mailto:alice@example.com) pour signature »
    * « Quelles Demandes de Signature sont en attente dans mon Espace de Travail Sales ? »
    * « Montre-moi la Piste d'Audit de la Demande de Signature X »
  </Tab>
</Tabs>

## Intégration webhook

Pour suivre les événements de signature en temps réel, enregistrez un Webhook Firma pointant vers un endpoint de votre application :

```javascript theme={null}
app.post("/api/firma-webhook", async (req, res) => {
  const { type, data } = req.body;

  if (type === "signing_request.completed") {
    const signingRequestId = data.signing_request.id;
    // Update your DB, trigger downstream automation, etc.
  }

  res.json({ received: true });
});
```

Dans le tableau de bord Firma, sous **Paramètres > Webhooks**, enregistrez l'URL de votre endpoint. Firma envoie des événements pour tous les changements d'état majeurs. Consultez le [guide des webhooks](/fr/guides/webhooks) pour la liste complète des événements et la vérification de signature.

<Warning>
  Vérifiez toujours la signature du webhook à l'aide de votre secret de signature de webhook Firma en production. Consultez le [guide des webhooks](/fr/guides/webhooks) pour les détails d'implémentation.
</Warning>

## Signature intégrée

Pour les applications où les Signataires complètent les documents directement dans votre interface plutôt que d'ouvrir une page hébergée par Firma, la réponse de `create-and-send` inclut `first_signer.id` (le `signing_request_user_id`) et un `first_signer.signing_link` prêt à l'emploi. Chargez l'URL du Signataire dans une iframe :

```html theme={null}
<iframe
  src="https://app.firma.dev/signing/{signing_request_user_id}"
  style="width:100%;height:900px;border:0;"
  allow="camera;microphone;clipboard-write"
  title="Document Signing"
></iframe>
```

Consultez le [guide de signature intégrée](/fr/guides/embeddable-signing) pour la configuration complète, y compris les bonnes pratiques de sécurité.

## Astuces

* **Utilisez le function calling pour les agents en exécution, MCP pour la construction.** Le function calling est ce que votre application déployée utilise pour envoyer des documents. Les serveurs MCP sont ce que vous et la CLI Codex utilisez pour construire cette intégration.
* **Passez `template_id` comme argument d'outil, pas comme chaîne libre.** Les Modèles sont le moyen le plus sûr de limiter ce que le modèle peut envoyer.
* **Validez avant d'envoyer.** Pour les documents à enjeux plus élevés, utilisez `POST /signing-requests` pour créer un brouillon, présentez-le à l'utilisateur, puis appelez `POST /signing-requests/{id}/send` seulement après leur confirmation.
* **Espaces de Travail pour les applications multi-tenant.** Si vous construisez un produit SaaS au-dessus de l'API OpenAI, donnez à chaque client final son propre Espace de Travail Firma afin que les Modèles et l'utilisation restent isolés.

## Prochaines étapes

* [Authentification API](/fr/guides/authentication) - Clés API et portée des Espaces de Travail
* [Guide des webhooks](/fr/guides/webhooks) - Types d'événements, payloads et vérification de signature
* [Signature intégrée](/fr/guides/embeddable-signing) - Expérience de signature intégrée à l'application
* [Création d'Espaces de Travail](/fr/guides/creating-workspaces) - Configurations multi-tenant pour les applications SaaS
* [Intégration MCP](/fr/guides/mcp) - Référence complète du serveur MCP avec les 84 outils
* [Guide de configuration complet](/fr/guides/complete-setup-guide) - Parcours d'intégration Firma de bout en bout
* [Référence API](/api-reference) - Documentation complète des endpoints
