✦API
Remplir vos documents à distance
Déposez un PDF depuis votre code, laissez l'IA poser ses questions, répondez, récupérez le document rempli. Le même moteur que le site, sans le site.
Le prix de l'API
L'API se paie à la page, comme le site : 80 pages par mois dès l'offre Essentiel (9 € par mois), ou 20 pages pour 2,50 € sans abonnement. Pour de gros volumes, l'offre Entreprise, sur devis.
Votre clé
Une clé s'obtient depuis votre compte, jamais par l'API elle-même. Elle se présente dans l'en-tête Authorization, comme un jeton Bearer.
La clé n'est affichée qu'une seule fois, à sa création. Nous n'en gardons qu'une empreinte : si vous la perdez, elle est irrécupérable — révoquez-la et créez-en une autre.
curl https://plumeai.fr/api/v2/dossiers \
-H "Authorization: Bearer plume_sk_votre_cle"Ce qu'une clé peut faire
Chaque clé porte des portées, choisies à sa création. Une clé n'a que les droits que vous lui donnez, et vous pouvez en créer une par usage : lecture seule pour un tableau de bord, écriture pour un automate.
fills:readLire un remplissage, ses questions et ses champs.fills:writeDéposer un document, répondre aux questions, écrire des champs, et poser le consentement au remplissage.fills:exportTélécharger le document rempli.moteur:carteDétecter les champs sans remplissage et lire leurs libellés, sans carte géométrique.conversations:readLire les conversations avec Pluma et leurs pièces jointes.conversations:writeParler à Pluma hors d'un dossier, joindre ou retirer une pièce, effacer une conversation.documents:readLire les documents de l'espace et ceux que Plume a produits.documents:writeÉpingler ou fusionner des documents, préparer une lettre.suivi:readLire les renouvellements, le suivi des formulaires, les notifications et les contacts.suivi:writeProgrammer un renouvellement, suivre un formulaire, marquer les notifications comme lues, oublier un contact.profils:readLire les personnes, leur mémoire, leurs justificatifs, leur signature et les durées de conservation.profils:writeCréer ou supprimer une personne ; modifier sa mémoire, ses justificatifs, sa signature et les durées de conservation.courriels:readLire la boîte mail, ses libellés et l'adresse d'import.courriels:writeEnvoyer un courriel ou y répondre en votre nom, classer les messages, régler l'adresse d'import.Aucune portée n'ouvre votre compte : une clé ne peut ni le supprimer, ni exporter vos données, ni toucher à la facturation, ni créer d'autres clés. Une clé qui fuite reste bornée à vos documents, et sa révocation suffit à refermer la porte.
Le parcours
Le contrat v2 suit le même dossier que le site : consentement, documents, personnes, renseignements et exports. Chaque appel exige la portée indiquée ; cumulez lecture, écriture et export pour le parcours complet.
Consulter le schéma OpenAPI v2/api/v1/soldefills:read / moteur:carteCe qu'il vous reste : pages du mois, pages achetées, quota de documents
/api/v1/consentsfills:write / moteur:carteLe consentement au remplissage, sans lequel le dépôt est refusé. Créé une fois, il vaut pour tous vos dépôts : c'est vous, titulaire de la clé, qui consentez pour votre espace. Un en-tête Idempotency-Key est requis, et la révocation se fait depuis votre compte.
/api/v2/dossiersfills:write / moteur:carteDépose un ou plusieurs fichiers avec une clé de reprise et un consentement. include_fill choisit le remplissage ou la détection seule ; pages_spec choisit les pages.
/api/fills-profilsfills:read / moteur:carteListe les profils existants. profile_id est facultatif au dépôt : les destinataires peuvent rester propres au dossier, sans profil enregistré.
/api/v2/dossiers/{id}/repartitionfills:read / fills:writeLit ou modifie les associations entre documents et personnes avec contrôle de révision. POST /repartition/preparer crée les seuls exemplaires demandés ; GET /exemplaires les liste.
/api/v2/dossiers/{id}/etatfills:read / moteur:carteOù en est le traitement : en attente, en cours, terminé.
/api/v2/dossiers/{id}/questionsfills:readLit les questions et les réponses déjà enregistrées. Cette lecture ne déclenche aucun appel à Pluma.
/api/v2/dossiers/{id}/answersfills:writeEnregistre les réponses par identifiant de question. fill_now=true demande leur application. Idempotency-Key est obligatoire.
/api/v2/dossiers/{id}/chatfills:read / fills:writeLit la conversation ou envoie un message à la même Pluma que le site. Un envoi exige Idempotency-Key ; une lecture ne réveille pas le modèle.
/api/v2/dossiers/{id}/piecesfills:read / fills:writeDépose ou liste les pièces PDF, image, TXT, CSV et XLSX. Joignez leurs identifiants au message ; Pluma décide de leur utilité selon le contexte.
/api/v2/dossiers/{id}/fields?page=1fills:read / moteur:carteLit les identifiants, libellés contextualisés, types, valeurs et version de la page, sans coordonnées.
/api/v2/dossiers/{id}/values?page=1fills:writeÉcrit seulement les valeurs des champs désignés. If-Match reprend la version lue et Idempotency-Key protège les reprises ; positions et libellés restent au serveur.
/api/v2/dossiers/{id}/cancelfills:write / moteur:carteDemande l’interruption. Relisez l’état pour distinguer une demande en attente d’un arrêt confirmé.
/api/v2/dossiers/{id}/export/preparationfills:exportFige les révisions, attributions et noms pour l’export. Le même instantané sert aux PDF et à GET /export/csv?instantane=….
/api/v2/dossiers/{id}/export/flatfills:exportPrépare un PDF aplati, ou un ZIP pour plusieurs exemplaires, à partir de l’instantané choisi. Répond 202 avec un lien de suivi.
/api/v2/dossiers/{id}/export/acroformfills:exportPrépare un PDF avec champs éditables, ou un ZIP d’exemplaires. Le suivi et la reprise suivent le même contrat que l’export aplati.
/api/v2/dossiers/{id}/exports/{command_id}/filefills:exportTélécharge le PDF ou le ZIP uniquement quand l’export a réussi. Respectez le nom et le type de fichier renvoyés.
Un exemple complet
Du consentement au document rempli, sans jamais ouvrir de navigateur.
Remplacez PLUME_CLE par votre clé ; CONSENT_ID et DOSSIER_ID proviennent des réponses précédentes. Chaque nouvelle opération reçoit sa propre clé de reprise. L’exemple suppose un consentement accordé et un fichier formulaire.pdf disponible.
curl -X POST https://plumeai.fr/api/v1/consents \
-H "Authorization: Bearer $PLUME_CLE" \
-H "Idempotency-Key: consent-001" \
-H "Content-Type: application/json" \
-d '{"purpose":"form_fill"}'
curl -X POST https://plumeai.fr/api/v2/dossiers \
-H "Authorization: Bearer $PLUME_CLE" \
-H "Idempotency-Key: import-001" \
-F "file=@formulaire.pdf" \
-F "consent_id=$CONSENT_ID" \
-F "include_fill=true" \
-F "pages_spec=all"
curl https://plumeai.fr/api/v2/dossiers/$DOSSIER_ID/etat \
-H "Authorization: Bearer $PLUME_CLE"
curl https://plumeai.fr/api/v2/dossiers/$DOSSIER_ID/questions \
-H "Authorization: Bearer $PLUME_CLE"
curl -X POST https://plumeai.fr/api/v2/dossiers/$DOSSIER_ID/chat \
-H "Authorization: Bearer $PLUME_CLE" \
-H "Idempotency-Key: message-001" \
-H "Content-Type: application/json" \
-d '{"message":"Mon prénom est Alice. Remplis les champs correspondants."}'Après la préparation, INSTANTANE reprend instantane. Le POST d’export rend 202 : conservez status_url dans STATUS_URL, puis attendez succeeded avant de reprendre download_url dans DOWNLOAD_URL. Une réponse 202 n’est pas un PDF.
curl https://plumeai.fr/api/v2/dossiers/$DOSSIER_ID/export/preparation \
-H "Authorization: Bearer $PLUME_CLE"
curl -X POST https://plumeai.fr/api/v2/dossiers/$DOSSIER_ID/export/acroform \
-H "Authorization: Bearer $PLUME_CLE" \
-H "Idempotency-Key: export-001" \
-H "Content-Type: application/json" \
-d "{\"instantane\":\"$INSTANTANE\"}"
curl "https://plumeai.fr$STATUS_URL" \
-H "Authorization: Bearer $PLUME_CLE"
curl --fail "https://plumeai.fr$DOWNLOAD_URL" \
-H "Authorization: Bearer $PLUME_CLE" -OJAprès une coupure, renvoyez la même requête avec la même clé. OPERATION_RUNNING demande d’attendre ; OPERATION_OUTCOME_UNKNOWN demande de relire conversation et valeurs avant de décider de la suite.
Détecter sans remplir
Utilisez le même dépôt avec include_fill=false. Aucun renseignement personnel n’est requis. Pour relancer, envoyez source_fill_id, analyse_explicite=true et les pages choisies. Ajoutez fills:export à moteur:carte pour télécharger le PDF éditable.
Après une relance complète, POST /conversation/amorcer reprend l’historique enregistré ; PUT /remplacement relie les deux dossiers. Les lectures suivent la nouvelle version (307), les anciennes écritures sont refusées (409) et les exports déjà demandés restent disponibles. Une relance partielle ne remplace pas implicitement tout le document. La réanalyse d’un dossier déjà attribué à plusieurs personnes n’est pas encore disponible.
Le JSON et le CSV public ne livrent ni rectangles, ni masques, ni scores du moteur. Un PDF AcroForm contient nécessairement la position de ses champs éditables ; un export aplati conserve le résultat visuel.
Migration : les anciennes routes /api/v1/carte et /api/v1/juge répondent 410. Les clés n’accèdent plus aux routes internes /api/fills. Utilisez /api/v2/dossiers ; le nom de portée moteur:carte reste accepté pour la détection seule.
Webhooks : être prévenu au lieu d'attendre
Sans webhook, il ne vous reste qu'à interroger l'état du dossier en boucle, pour n'apprendre presque jamais rien. Déclarez une adresse et Plume l'appelle une fois, quand le dossier est fini — ou quand il a échoué. L'échec compte autant : sans lui, votre programme attend un document qui ne viendra jamais.
Le corps ne contient aucune donnée personnelle ni contenu de document : ni nom de fichier, ni champ détecté, ni valeur écrite. Il dit qu'un dossier est fini, lequel, et avec quel état. Le reste se lit par l'API, avec votre clé.
Une adresse se déclare par l'appel ci-dessous, et par lui seul : il n'existe pas d'écran de gestion des webhooks. L'appel s'authentifie avec votre session de connexion — vous devez être owner ou admin de l'espace ; présenté avec une clé d'API, il répond 403. Cinq adresses au maximum par espace.
POST https://plumeai.fr/api/v1/tenants/{espace}/webhooks
{"url": "https://votre-serveur.fr/plume/webhook"}
# → {"id": "whk_…", "secret": "whsec_…"}
# Le secret n'est rendu QU'ICI. Copiez-le : il ne sera plus jamais affiché.
# Un envoi de test, tout de suite, pour valider votre point de terminaison :
POST /api/v1/tenants/{espace}/webhooks/{id}/pingCe que votre serveur reçoit :
POST https://votre-serveur.fr/plume/webhook
Content-Type: application/json
X-Plume-Event: fill.done
X-Plume-Timestamp: 2026-08-27T10:00:00+00:00
X-Plume-Delivery: 3f9a1c4e7b20d8a6
X-Plume-Signature: sha256=21e667659d1a7a94…
{"created_at":"2026-08-27T10:00:00+00:00","event":"fill.done",
"fill_id":"fill_abc","pages":3,"status":"succeeded","tenant_id":"tenant_x"}
# event : "fill.done" (terminé, même partiellement) ou "fill.failed" ;
# "fill.share_completed" / "fill.share_declined" : une personne a
# rempli, ou refusé, la partie confiée par un lien
# status : succeeded | partial | awaiting_answers | failed
# (termine | refuse pour un lien)
# pages : nombre de pages demandées au dépôt, ou null si « all »Vérifiez toujours la signature avant de traiter l'appel. Sans elle, n'importe qui connaissant votre adresse peut vous annoncer de faux dossiers.
# Les OCTETS BRUTS du corps, jamais un JSON re-sérialisé.
corps = requête.corps_brut
attendue = "sha256=" + hmac_sha256(clé = votre_secret, message = corps).hex()
si non comparaison_à_temps_constant(attendue, en_tête("X-Plume-Signature")):
répondre 401 et s'arrêter
# L'horodatage n'entre PAS dans la signature : refusez simplement ce qui est
# plus vieux que quelques minutes.
si maintenant() - date(en_tête("X-Plume-Timestamp")) > 5 minutes:
répondre 400 et s'arrêter
# fill_id est votre clé d'idempotence : le même dossier peut arriver deux
# fois si notre réseau a coupé après votre réponse.
si déjà_traité(corps.fill_id): répondre 200 et s'arrêterNous réessayons trois fois, à quelques secondes d'intervalle, uniquement sur panne (5xx, 429, coupure réseau). Un 404 ou un 401 n'est pas réessayé. Répondez vite : au-delà de cinq secondes, la tentative est abandonnée — accusez réception, traitez ensuite.
Seules les adresses https publiques sont acceptées. Une adresse locale ou privée est refusée à l'enregistrement, et de nouveau au moment de l'envoi : un nom de domaine qui pointerait vers un réseau interne ne recevra rien.
Les erreurs
401Clé absente, inconnue, expirée ou révoquée.403La clé est valide, mais sa portée ne couvre pas cette route.402Solde ou offre insuffisants. Vérifiez le coût annoncé et obtenez l’accord de l’utilisateur avant tout dépassement.404Ce remplissage n'existe pas, ou n'appartient pas à votre compte.409Version obsolète, clé de reprise réutilisée pour une autre demande, opération en cours ou résultat incertain. Relisez l’état avant une nouvelle action.410Ancien contrat retiré. Utilisez la route de remplacement indiquée.422Paramètre, fichier ou corps invalide. Corrigez la demande avant de réessayer.428Idempotency-Key ou If-Match requis pour cette opération.429Trop d'appels. Ralentissez et réessayez.Sécurité
Traitez une clé comme un mot de passe : hors du dépôt Git, hors du code exécuté par le navigateur, dans une variable d'environnement ou un gestionnaire de secrets. Si vous pensez qu'une clé a fuité, révoquez-la d'abord et enquêtez ensuite — la révocation est immédiate.
Les documents envoyés par l'API suivent exactement les mêmes règles que ceux déposés sur le site : mêmes durées de conservation, même chiffrement, même fournisseur d'IA. Voir la politique de confidentialité.