# Envoyer une demande avec l'API REST

Créez un token API, lisez les clés de champ d'un formulaire, et créez une demande préremplie avec curl, depuis n'importe quel outil capable de faire un appel HTTP.

## Envoyer une demande avec l'API REST

N'importe quel outil avec une étape HTTP peut envoyer une demande : Pipedream, une fonction serverless, un script. Ce guide le fait avec curl, pour que vous puissiez voir chaque appel avant de le porter dans votre propre code.

<p>
  Il vous faut un formulaire publié. Ce guide utilise celui construit dans{' '}
  <a href="/fr/guides/ai-agents/build-a-form">Construire un formulaire avec un agent IA</a> : nom de l'entreprise, e-mail de contact, numéro
  de TVA, une question oui ou non sur les conditions de paiement, et un téléversement de fichier. Chaque méthode et option utilisée ici est
  décrite dans <a href="/fr/developers/rest-api">Méthodes API</a>.
</p>

<h2 id="token">1. Créez un token API</h2>

<p>
  Dans formbase, ouvrez <strong>OAuth et clés API</strong> dans la barre latérale de l'espace de travail et{' '}
  <a href="/fr/developers/api-tokens#create">créez un token</a>. La valeur n'est affichée qu'une fois. Gardez-la dans une variable
  d'environnement, pas dans votre code :
</p>

```
export FORMBASE_TOKEN='fb_...'
```

<p>
  Un token n'atteint que l'espace de travail dans lequel il a été créé. Chaque appel ci-dessous est un <code>POST</code> vers la même URL
  avec le token dans l'en-tête <code>Authorization</code> ; le corps nomme la méthode et ses paramètres.
</p>

<h2 id="form-id">2. Trouvez l'ID du formulaire</h2>

<p>
  Ouvrez le formulaire dans l'éditeur. L'ID du formulaire est la partie de l'adresse après <code>/forms/</code> :
</p>

```
https://app.formbase.so/<workspace ID>/forms/jx75hdx8vb5hy1x85gm17nqgkn8f674g/edit
```

<p>Les commandes ci-dessous utilisent l'ID de formulaire de ce guide. Mettez le vôtre à sa place.</p>

<h2 id="fields">3. Listez les clés de champ</h2>

<p>
  Une demande remplit des questions, et les réponses reviennent, par <a href="/fr/requests/field-keys">clé de champ</a>. Demandez au
  formulaire ses clés plutôt que de les deviner à partir des titres :
</p>

```
curl -X POST https://api.formbase.so/api/v1 \
  -H "Authorization: Bearer $FORMBASE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"method": "fields.list", "params": {"formId": "jx75hdx8vb5hy1x85gm17nqgkn8f674g"}}'
```

<p>La réponse liste chaque question du formulaire publié. Raccourcie :</p>

```
{
  "ok": true,
  "data": {
    "published": true,
    "items": [
      { "key": "company_name", "type": "text", "title": "Company name", "required": true, "prefillable": true },
      { "key": "contact_email", "type": "email", "title": "Contact email", "required": true, "prefillable": true },
      { "key": "vat_number", "type": "text", "title": "VAT number", "required": false, "prefillable": true },
      {
        "key": "do_you_accept_our_30_day_payment_terms", "type": "radio", "title": "Do you accept our 30-day payment terms?", "required": true, "prefillable": true,
        "options": [{ "key": "yes", "label": "Yes" }, { "key": "no", "label": "No" }]
      },
      { "key": "certificate_of_incorporation", "type": "file", "title": "Certificate of incorporation", "required": true, "prefillable": false }
    ],
    "hasMore": false
  }
}
```

<p>
  Pour préremplir une question à choix, envoyez la <code>key</code> de l'option, ici <code>"yes"</code>, pas son libellé. Une question avec{' '}
  <code>prefillable: false</code>, comme le téléversement de fichier, seul le destinataire peut y répondre. Les autres indicateurs sont
  expliqués sous <a href="/fr/developers/rest-api#fields-list">fields.list</a>.
</p>

<h2 id="create">4. Créez une demande de test</h2>

<p>
  Envoyez la demande à Ada Lovelace, avec le nom de l'entreprise rempli et verrouillé. <code>test: true</code> en fait une{' '}
  <a href="/fr/requests/creating-requests#test-mode">demande de test</a> : elle n'envoie jamais d'e-mail à personne et ne compte nulle part,
  vous pouvez donc répéter cette étape aussi souvent que vous voulez, avec un nouveau <code>idempotencyKey</code> à chaque fois.
</p>

```
curl -X POST https://api.formbase.so/api/v1 \
  -H "Authorization: Bearer $FORMBASE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "method": "requests.create",
    "params": {
      "formId": "jx75hdx8vb5hy1x85gm17nqgkn8f674g",
      "recipient": { "email": "ada@acme.example", "name": "Ada Lovelace" },
      "prefill": { "company_name": "Analytical Engines Ltd" },
      "readonly": ["company_name"],
      "externalId": "supplier-2043",
      "idempotencyKey": "supplier-2043",
      "test": true
    }
  }'
```

<ul>
  <li>
    <strong>prefill</strong> remplit des réponses que le destinataire peut encore modifier. Une clé dans <strong>readonly</strong> est aussi{' '}
    <a href="/fr/requests/creating-requests#locked-fields">verrouillée</a>.
  </li>
  <li>
    <strong>externalId</strong> est votre propre id pour cette tâche, comme un numéro de fournisseur. Il revient sur chaque lecture et
    chaque callback.
  </li>
  <li>
    <strong>idempotencyKey</strong> rend une nouvelle tentative sûre. Si votre code envoie le même appel deux fois, formbase renvoie la
    première demande avec <code>deduplicated: true</code> au lieu d'en créer une seconde.
  </li>
</ul>

<p>La réponse porte l'ID de la demande et le lien pour le destinataire :</p>

```
{
  "ok": true,
  "data": {
    "id": "m17ayhcnj9xvzkff3atek49bdd8f6872",
    "status": "pending",
    "url": "https://form.formbase.so/r/rq_...",
    "deliveryStatus": "not_requested",
    "externalId": "supplier-2043",
    "deduplicated": false,
    "createdAt": 1790539225370,
    "expiresAt": 1793131225370
  }
}
```

<p>
  <code>deliveryStatus: "not_requested"</code> signifie que formbase n'a envoyé aucun e-mail ; vous livrez le lien vous-même. Pour que
  formbase envoie l'invitation et les rappels, ajoutez <code>"delivery": "email"</code>, ce qui nécessite un plan Pro ou Business. Voir{' '}
  <a href="/fr/requests/invitations-and-reminders">Invitations, rappels et expiration</a>. Si le formulaire a{' '}
  <strong>Send reminders</strong> activé, une vraie demande avec un e-mail de destinataire reçoit quand même les rappels programmés ;
  ajoutez <code>"reminders": []</code> pour n'en envoyer aucun.
</p>

> ℹ️ **Les demandes de test restent invisibles**
> <p>
>     La page <strong>Demandes</strong> ne liste les demandes de test que quand vous activez le filtre{' '}
>     <strong>Afficher les demandes de test</strong>. Ouvrez <code>url</code> vous-même pour la compléter. Retirez <code>test</code> quand
>     vous envoyez la demande réelle.
>   </p>

<h2 id="read">5. Complétez-la et lisez les réponses</h2>

<p>
  Ouvrez <code>url</code> dans un navigateur. Le nom de l'entreprise est rempli et verrouillé ; répondez au reste et soumettez. Puis relisez
  la demande avec son ID :
</p>

```
curl -X POST https://api.formbase.so/api/v1 \
  -H "Authorization: Bearer $FORMBASE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"method": "requests.get", "params": {"requestId": "m17ayhcnj9xvzkff3atek49bdd8f6872"}}'
```

<p>
  Une fois que <code>status</code> vaut <code>completed</code>, la réponse porte deux maps indexées par clé de champ. <code>answers</code>{' '}
  est pour le code : une réponse à choix est la clé de l'option, une réponse fichier est une liste de fichiers avec des liens de
  téléchargement. <code>display</code> est pour les humains : des libellés et des noms de fichiers.
</p>

```
"answers": {
  "company_name": "Analytical Engines Ltd",
  "do_you_accept_our_30_day_payment_terms": "yes",
  "certificate_of_incorporation": [{ "name": "certificate-of-incorporation.pdf", "type": "application/pdf", "size": 635, "url": "https://api.formbase.so/api/storage/..." }]
},
"display": {
  "company_name": "Analytical Engines Ltd",
  "do_you_accept_our_30_day_payment_terms": "Yes",
  "certificate_of_incorporation": "certificate-of-incorporation.pdf"
}
```

<p>
  Redemander sans cesse jusqu'à ce que le statut change fonctionne pour un test, mais pas en production. Donnez à la demande une{' '}
  <code>callbackUrl</code> et formbase vous appelle quand elle se termine ; le guide suivant met ça en place.
</p>

<h2 id="next">Suite</h2>

<div class="not-prose grid gap-3 sm:grid-cols-2 mb-8">
  - [Recevoir et vérifier le callback](/fr/guides/rest-api/verify-the-callback) — Récupérez les réponses envoyées à votre endpoint, et vérifiez que c'est bien formbase qui les a envoyées.
  - [Créer une demande](/fr/requests/creating-requests) — Toutes les options qu'une demande prend : contexte, métadonnées, documents, expiration.
</div>
