Documentation
Demandez à qui il faut depuis votre agent.
Votre agent décrit ce dont il a besoin (un formulaire, une enquête, ou un oui ou un non) et reçoit un lien pour une personne, pour chaque personne d’un groupe, ou pour toute personne à qui vous le transmettez. Les gens l’ouvrent sur leur téléphone, sans inscription, et leurs réponses vous reviennent sous forme de JSON validé.
-
Créez une demande. Appelez
createRequestavec un JSON Schema pour un formulaire, ou un motif pour une approbation. -
Envoyez le lien. Passez
sendEmail: trueet nous l’envoyons par e-mail à chaque personne nommée, transmettez-le par un canal que vous avez déjà (e-mail, chat ou SMS), ou publiez un lien ouvert où vous voulez. -
Récupérez la réponse. Avec Builder et Pro, votre client MCP reçoit chaque réponse en push dès qu’elle arrive. Elle arrive aussi sur votre webhook, par e-mail avec
notifyEmail, ou vous la lisez avecgetStatus.
Les mêmes outils sont disponibles de deux façons : un serveur MCP pour les agents qui parlent MCP, et une API REST pour tout le reste. Les agents peuvent lire ce guide dans llms.txt.
Démarrage rapide
D’une clé API à la réponse d’une personne en quatre étapes.
1Obtenez une clé API
Connectez-vous avec votre e-mail et copiez la clé depuis le tableau de bord. Elle commence par sk_live_ ; gardez-la sur votre serveur. Vous utilisez Claude Code, Codex ou un autre client MCP ? Passez cette étape : ajoutez le serveur par URL et connectez-vous depuis le client.
2Créez une demande
Celle-ci demande à Jordan une adresse de livraison et une date de livraison. Le schéma est du JSON Schema classique ; voir Schéma du formulaire pour ce qui est pris en charge.
3Envoyez le lien
La réponse contient un lien par personne dans links[] (ou une seule url pour un lien ouvert). Avec "sendEmail": true, nous envoyons à chaque personne nommée qui a une adresse e-mail son propre lien, au nom de votre compte. Le champ email de chaque lien indique ce qui s’est passé : "sent", "failed" (la demande existe quand même ; appelez remind plus tard), "limit" (les limites d’e-mails du forfait sont atteintes), "no address" ou "off". Envoyez les autres comme vous voulez : e-mail, chat ou SMS.
4Récupérez la réponse
Quand Jordan valide, votre webhookUrl reçoit un événement response.created avec les données, déjà vérifiées par rapport à votre schéma. Pas de webhook ? Appelez getStatus avec le requestId, renseignez notifyEmail et nous vous écrivons quand c’est terminé, ou, avec Builder et Pro, abonnez-vous en MCP et votre agent est prévenu dès que Jordan répond. Voir Récupérer les réponses.
Authentification
Chaque appel MCP et REST envoie une clé API comme jeton bearer. La même clé fonctionne pour les deux. Une clé manquante ou révoquée reçoit un 401. Il y a deux façons d’en obtenir une.
Connectez-vous depuis votre client MCP
Ajoutez https://runitby.app/mcp sans clé et le client vous connecte via OAuth : un navigateur s’ouvre, vous saisissez votre e-mail, et le lien de connexion vous ramène sur une page qui vous demande d’autoriser l’appli. Première fois ? Le même lien crée votre compte. L’appli détient ensuite sa propre clé, à son nom, que vous pouvez révoquer dans Clés.
-
Claude Code : exécutez la commande de droite, puis
/mcpdans Claude Code et choisissez de vous authentifier. -
Codex : exécutez
codex mcp add, puiscodex mcp login. - Claude (web et bureau) : Paramètres, Connecteurs, Ajouter un connecteur personnalisé, et collez l’URL.
- Autres clients compatibles avec l’autorisation MCP : ajoutez l’URL sans en-têtes.
Créez une clé dans le tableau de bord
Pour l’API REST, les scripts et les clients qui n’acceptent qu’un en-tête : créez et révoquez les clés dans le tableau de bord et envoyez la clé dans l’en-tête Authorization.
Les formules comptent les deux séparément. Free inclut une clé et une appli connectée, Builder cinq de chaque, Pro autant qu’il vous en faut.
Exemples en un seul fichier avec une clé : Vercel AI SDK, Mastra, LangChain.js et le Claude Agent SDK.
Outils et endpoints
Chaque outil MCP a un endpoint REST avec les mêmes entrées et sorties. La référence de l’API liste chaque champ.
| Outil MCP | REST | Ce qu’il fait |
|---|---|---|
createRequest |
POST /requests | Crée un formulaire ou une approbation et renvoie le ou les liens, envoyés par e-mail pour vous si vous le demandez. |
previewRequest |
POST /requests/preview | Captures et vérifications de ce que la personne verra. Ne crée rien. |
getStatus |
GET /requests/{id} | Statut, verdict et toutes les réponses reçues jusqu’ici. |
listRequests |
GET /requests | Vos demandes, de la plus récente à la plus ancienne. Filtrez par mode ou statut ; paginez avec cursor. |
updateRequest |
PATCH /requests/{id} | Modifie le contenu, ajoute des destinataires ou fixe une nouvelle expiration. |
remind |
POST /requests/{id}/remind | Envoie le lien par e-mail aux personnes qui n’ont pas répondu. |
closeRequest |
DELETE /requests/{id} | Cesse d’accepter des réponses. |
Formulaires et approbations
Chaque demande a un mode :
"form"- Collecter des données. Vous envoyez un
schema; la personne reçoit un formulaire construit à partir de celui-ci, et vous récupérez un objet conforme. "approval"- Obtenir une décision. Vous envoyez
approval.reason; chaque personne reçoit une carte avec Approuver et Refuser (ou vos propres libellés) et un commentaire facultatif. Vous récupérez chaque décision et unverdictglobal.
Les deux acceptent un title (jusqu’à 120 caractères), une ligne requester facultative indiquant qui demande, une locale pour la page et ses e-mails ("en", "es", "pt", "fr", "de", "it", "ja" ou "zh", ou avec une région comme "es-AR" pour les dates), et des metadata qui reviennent intactes dans chaque webhook et chaque statut. Rédigez le titre et les questions dans la même langue.
Qui répond
audience détermine qui reçoit un lien.
| kind | Vous obtenez | À utiliser pour |
|---|---|---|
"named" |
links[], un par personne dans recipients (de 1 à 50, chacun { name, email?, phone? }) |
Des réponses que vous devez attribuer à quelqu’un. Les approbations doivent être nominatives. Une adresse e-mail active sendEmail, les relances et les codes par e-mail. |
"open" |
Une url que tout le monde peut ouvrir |
Inscriptions et enquêtes. maxSubmissions plafonne les réponses (1 par défaut). |
À quoi ça sert
Un mode et une audience couvrent l’essentiel de ce que vous feriez autrement avec un outil de formulaires, un sondage, une appli de planification ou un fil d’e-mails.
| Vous voulez | Demande |
|---|---|
| Les informations d’une personne : adresse de livraison, accueil d’un client, créneau de réservation | "form", nommée, un destinataire |
| Une enquête, un sondage, des retours ou des inscriptions de la part de n’importe qui |
"form", ouverte avec maxSubmissions. Publiez l’unique url où vous voulez ; getStatus renvoie toutes les réponses pour que votre agent les synthétise. |
| Confirmations de présence, disponibilités, remplacements de service ou points de situation d’un groupe connu |
"form", nommée (jusqu’à 50), pour que chaque réponse soit attribuée et que remind relance les autres |
| Approbations, validations et votes |
"approval" avec une policy ; ajoutez verify: "email" pour l’argent, les accès ou les suppressions |
Statut et expiration
| status | Signifie |
|---|---|
pending |
Personne n’a encore répondu. |
partial |
Certaines personnes nommées ont répondu, d’autres non. |
complete |
Tout le monde a répondu, maxSubmissions est atteint, ou une approbation a son verdict. |
expired |
Le lien a expiré. |
closed |
Vous avez appelé closeRequest. |
Expiration. expiresIn accepte "30m", "48h", "7d" ou des secondes. La valeur par défaut est de 7 jours et le maximum de 90.
Modifier une demande. updateRequest modifie le titre, le schéma, les sections, le motif ou le thème jusqu’à l’arrivée de la première réponse. L’ajout de destinataires, une nouvelle expiration (comptée à partir de maintenant) et la modification de notifyEmail fonctionnent tant que la demande n’est ni terminée, ni expirée, ni clôturée. Les destinataires ajoutés ne reçoivent pas d’e-mail ; envoyez-leur leurs liens ou appelez remind avec leurs recipientIds.
Relances. remind envoie le lien par e-mail aux personnes nommées qui n’ont pas répondu et ont une adresse e-mail, au plus une fois toutes les 24 heures chacune. L’e-mail de sendEmail compte comme le premier.
Récupérer les réponses. Utilisez-en un ou combinez-en plusieurs :
webhookUrl- Votre serveur reçoit chaque réponse au fil de l’eau. Voir Webhooks.
notifyEmail- Nous envoyons à votre compte un e-mail avec un résumé et un lien vers la demande dans le tableau de bord :
"each"à chaque réponse (jusqu’à ce que les limites d’e-mails du forfait soient atteintes, puis seulement à la fin), ou"complete"une seule fois quand la demande est terminée ou expire. Les e-mails d’approbation incluent la décision et le commentaire ; les réponses aux formulaires restent dans le tableau de bord. Désactivé par défaut ;updateRequestpeut le modifier. getStatusavecwait- Retient l’appel jusqu’à 25 secondes (REST :
?wait=25) et rend la main dès que quelqu’un répond ou que le statut change. Rappelez-le pour continuer à attendre. - MCP push (Builder et Pro)
- Chaque demande est la ressource MCP
runitby://requests/{requestId}, liée depuiscreateRequest; sa lecture renvoie la même chose quegetStatus. Avec Builder et Pro, les clients du protocole 2026-07-28 peuvent s’abonner avecsubscriptions/listenet recevoirnotifications/resources/updatedà chaque réponse ou changement de statut, avec un abonnement ouvert à la fois sur Builder et jusqu’à trois sur Pro. Sur Free,subscriptions/listenrépond par une erreur qui indique les autres moyens de récupérer les réponses.
Schéma du formulaire
Du JSON Schema classique avec type: "object" à la racine et jusqu’à 40 champs. required[] est appliqué, et title et description deviennent le libellé et le texte d’aide.
| Type | Mots-clés |
|---|---|
string |
format (email, date, time, date-time, tel, uri, duration), minLength, maxLength, pattern
|
number, integer |
minimum, maximum |
boolean |
const: true crée une case de consentement à cocher obligatoirement |
enum |
Une liste fixe de choix |
array |
De primitives ou d’un enum ; minItems, maxItems |
Indications. Placez les options propres à chaque champ dans "x-runitby" : widget, placeholder, help, columns (1 ou 2), step et currency.
Sections. Regroupez les champs avec sections: [{ title, fields: [...] }] à côté du schéma.
Les objets imbriqués (sauf le champ de localisation), oneOf, anyOf, allOf et $ref sont refusés avec un message qui indique quoi modifier. Les champs demandant des mots de passe, des codes PIN, des numéros de carte, des CVV, des codes de sécurité, des numéros de sécurité sociale ou des codes à usage unique sont refusés.
Types de champs
Des champs prêts à l’emploi pour ce que les gens trouvent pénible à saisir. Chacun est du JSON Schema ordinaire plus un widget, si bien que la réponse est validée comme n’importe quel autre champ.
| Champ | Schéma | Réponse |
|---|---|---|
| Date | string, format date | "2026-11-12" |
| Heure | string, format time ; step = minutes (1–60) | "14:30" |
| Date et heure | string, format date-time | "2026-11-12T14:30:00-08:00" |
| Durée | string, format duration | "PT1H30M" |
| Créneaux | tableau d’enum date-time, widget slots | les créneaux choisis |
| Plage de dates | tableau de 2 dates, widget daterange | ["2026-11-12", "2026-11-15"] |
| Localisation | object, widget location | { latitude, longitude, accuracy } |
| Montant | number, currency "USD" | 1200 |
| Curseur, note | number ou integer ; slider exige minimum et maximum | 7 |
| Pastilles, boutons radio, liste déroulante | enum (les pastilles acceptent aussi un tableau d’enum) | "M" |
| Classement | tableau d’enum, widget rank | toutes les options, dans l’ordre choisi par la personne |
| Oui ou non | boolean, widget yesno | true |
| Couleur | string, widget color | "#C2410C" |
| Pays | string, widget country | "US" (ISO 3166-1) |
| Langue | string, widget language | "es-AR" (BCP 47) |
| Fuseau horaire | string, widget timezone | "America/New_York" |
Ajoutez un enum à un champ de pays ou de langue pour limiter les choix.
Aperçu
previewRequest accepte les mêmes champs de formulaire ou d’approbation que createRequest (sans audience, expiration, webhook ni metadata) et renvoie des captures de 390 px et 1280 px de large, plus lint[] avec tout ce qui se lira mal. Rien n’est créé.
Passez sampleData pour voir le formulaire rempli, et viewports pour n’obtenir qu’une seule taille. Faites un aperçu d’abord quand le même formulaire sera envoyé de nombreuses fois.
Thèmes
theme donne à la page l’allure de votre produit. Sans lui, les pages sont en encre sur blanc chaud, avec Figtree et des titres en Fraunces, aux coins arrondis.
| Clé | Valeurs |
|---|---|
accent, background, surface,
text
|
Couleurs hexadécimales |
font, headingFont |
system, Figtree, Geist, Inter, DM Sans, Manrope, Work Sans, Space Grotesk, IBM Plex Sans, Fraunces, Lora, Source Serif 4 |
radius |
sharp, soft, round |
density |
compact, comfortable |
layout |
stacked (tous les champs sur une page) ou single (une question à la fois) |
logoUrl |
Votre logo |
heroText, thankYou |
Le message d’accueil au-dessus du formulaire et le message après l’envoi |
Options d’approbation
Les approbations exigent une audience nommée : chaque personne reçoit son propre lien, si bien que chaque décision lui est attribuée. Le verdict est "approved", "declined", ou "expired" quand personne n’a décidé à temps ; jamais un oui silencieux.
| champ approval | Par défaut | Notes |
|---|---|---|
reasonobligatoire |
Ce que vous demandez, jusqu’à 300 caractères. | |
detail |
Contexte sous le motif, jusqu’à 1 000 caractères. | |
policy |
"all" |
"any", "all", "majority" ou { n } : le nombre d’approbations requis. |
options |
Approuver, Refuser | De deux à quatre libellés ; le premier compte comme une approbation. Les décisions reviennent en snake_case : « Approve with changes » → "approve_with_changes". |
allowComment |
true | Permet d’ajouter un commentaire à sa décision. |
showOthers |
false |
"names" ou "counts" montre à chacun où en sont les autres. |
verify |
false |
"email" : chaque personne confirme un code à 6 chiffres envoyé à sa propre adresse avant que les boutons fonctionnent, si bien qu’un lien transféré ne peut pas décider à sa place. Chaque destinataire doit avoir une adresse e-mail. À utiliser pour l’argent, les accès ou les suppressions. |
Webhooks
Renseignez webhookUrl (https) sur une demande et nous y envoyons un POST JSON pour deux événements :
response.created- Chaque envoi ou chaque décision, avec la réponse dans
response. request.completed- Chaque personne nommée a répondu,
maxSubmissionsest atteint, une approbation a son verdict, ou la demande a expiré.
Vérifiez la signature. X-Runitby-Signature est le HMAC-SHA256 en hexadécimal du corps brut avec le secret de signature de votre compte, disponible dans le tableau de bord. X-Runitby-Timestamp est l’heure d’envoi en secondes Unix.
Nouvelles tentatives. Toute réponse 2xx en moins de 10 secondes compte comme livrée. Sinon, nous réessayons 4 fois, 1 min, 5 min, 30 min et 2 h après chaque échec. Ensuite, la réponse reste disponible dans getStatus.
Erreurs
Les erreurs sont du JSON avec un message lisible et, pour une entrée invalide, problems[] qui désigne chaque champ à modifier. Les agents peuvent généralement corriger la demande à partir du seul message.
| Statut | Quand |
|---|---|
400 |
L’entrée ou le schéma n’est pas valide. |
401 |
Clé API manquante ou révoquée. |
404 |
Aucune demande avec cet identifiant sur votre compte. |
409 |
La modification n’est plus autorisée, par exemple modifier après la première réponse ou relancer une demande clôturée. |
429 |
Plus de 60 créations par minute, ou les demandes mensuelles de la formule sont épuisées. |
Formules et limites
| Free | Builder | Pro | |
|---|---|---|---|
| Demandes par mois | 250 | 2,000 | 10,000 |
| Réponses par lien ouvert | 25 | 10,000 | Illimité |
| Clés API | 1 | 5 | Illimité |
| Applis connectées (OAuth) | 1 | 5 | Illimité |
| Réponses conservées après livraison | 30 jours | 90 jours | Conservées |
| E-mails par mois | 500 | 4,000 | 20,000 |
| E-mails par demande | 10 | 10 | 10 |
| MCP push (abonnements ouverts) | — | 1 | 3 |
| Prix par mois | $0 | $9 | $29 |
Au-delà de la limite mensuelle, createRequest renvoie 429 jusqu’à la réinitialisation de la période ou jusqu’à ce que vous changiez de formule (avec Pro, c’est la limite d’usage raisonnable : écrivez-nous pour en obtenir plus) ; les liens déjà envoyés continuent de fonctionner. Sans webhook, les réponses sont conservées à partir de leur envoi. Voir les tarifs.
Les e-mails que nous envoyons pour vous (liens, rappels et mises à jour notifyEmail) comptent dans les deux limites d’e-mails. Au-delà de l’une ou l’autre, les liens reviennent avec "limit" pour que vous les envoyiez vous-même et les mises à jour "each" s’arrêtent. L’e-mail annonçant la fin d’une demande part toujours, et les codes d’approbation ne comptent pas.
Sur toutes les formules : 60 créations par minute et par clé API, title jusqu’à 120 caractères, approval.reason 300, approval.detail 1 000 et metadata moins de 4 Ko.
Vous êtes le responsable du traitement des données que vous collectez. Ne demandez que ce dont la tâche a besoin.