Documentazione

Chiedi a chi serve dal tuo agente.

Il tuo agente descrive cosa gli serve (un modulo, un sondaggio, oppure un sì o un no) e riceve un link per una persona, per ogni persona di un gruppo o per chiunque tu voglia. Le persone lo aprono dal telefono, senza registrarsi, e le loro risposte ti tornano come JSON validato.

  1. Crea una richiesta. Chiama createRequest con un JSON Schema per un modulo, oppure con un motivo per un’approvazione.
  2. Manda il link. Passa sendEmail: true e lo inviamo per email a ogni destinatario nominativo, mandalo tu su un canale che hai già (email, chat o SMS) oppure pubblica un link aperto dove vuoi.
  3. Ricevi la risposta. Su Builder e Pro, al tuo client MCP arriva ogni risposta appena viene data. Arriva anche al tuo webhook, per email con notifyEmail, oppure la leggi con getStatus.

Gli stessi strumenti sono disponibili in due modi: un server MCP per gli agenti che parlano MCP e un’API REST per tutto il resto. Gli agenti possono leggere questa guida in llms.txt.

Guida rapida

Da una chiave API alla risposta di una persona in quattro passi.

1Ottieni una chiave API

Accedi con la tua email e copia la chiave dalla dashboard. Inizia con sk_live_; tienila sul tuo server. Usi Claude Code, Codex o un altro client MCP? Salta questo passo: aggiungi il server tramite URL e accedi dal client.

2Crea una richiesta

Questa chiede a Jordan un indirizzo di spedizione e una data di consegna. Lo schema è un normale JSON Schema; in Schema del modulo trovi cosa è supportato.

3Manda il link

La risposta contiene un link per persona in links[] (oppure un solo url per un link aperto). Con "sendEmail": true mandiamo a ogni destinatario nominativo che ha un’email il suo link personale, a nome del tuo account. L’email di ogni link dice cosa è successo: "sent", "failed" (la richiesta esiste comunque; chiama remind più tardi), "limit" (sono stati raggiunti i limiti di email del piano), "no address" oppure "off". Gli altri mandali come preferisci: email, chat o SMS.

4Ricevi la risposta

Quando Jordan invia, il tuo webhookUrl riceve un evento response.created con i dati, già verificati rispetto al tuo schema. Non hai un webhook? Chiama getStatus con il requestId, imposta notifyEmail e ti scriviamo quando è finita, oppure su Builder e Pro iscriviti via MCP e il tuo agente viene avvisato appena Jordan risponde. Vedi Ricevere la risposta.

Autenticazione

Ogni chiamata MCP e REST invia una chiave API come bearer token. La stessa chiave vale per entrambe. Una chiave mancante o revocata riceve un 401. Ci sono due modi per ottenerne una.

Accedi dal tuo client MCP

Aggiungi https://runitby.app/mcp senza chiave e il client ti fa accedere tramite OAuth: si apre un browser, inserisci la tua email e il link di accesso ti riporta a una pagina che ti chiede di autorizzare l’app. Prima volta? Lo stesso link crea il tuo account. L’app conserva poi una propria chiave, che porta il suo nome e che puoi revocare in Chiavi.

  • Claude Code: esegui il comando a destra, poi /mcp in Claude Code e scegli di autenticarti.
  • Codex: esegui codex mcp add, poi codex mcp login.
  • Claude (web e desktop): Impostazioni, Connettori, Aggiungi connettore personalizzato, e incolla l’URL.
  • Altri client che supportano l’autorizzazione MCP: aggiungi l’URL senza header.

Crea una chiave nella dashboard

Per l’API REST, gli script e i client che accettano solo un header: crea e revoca le chiavi nella dashboard e invia la chiave nell’header Authorization.

I piani contano le due cose separatamente. Free include una chiave e un’app collegata, Builder cinque di ciascuna, Pro quante ne servono.

Esempi in un solo file con una chiave: Vercel AI SDK, Mastra, LangChain.js e il Claude Agent SDK.

Strumenti ed endpoint

Ogni strumento MCP ha un endpoint REST con gli stessi input e output. Il riferimento API elenca ogni campo.

Strumento MCP REST Cosa fa
createRequest POST /requests Crea un modulo o un’approvazione e restituisce il link (o i link), inviati per email al posto tuo se lo chiedi.
previewRequest POST /requests/preview Screenshot e controlli di ciò che vedrà la persona. Non crea nulla.
getStatus GET /requests/{id} Stato, esito e tutte le risposte finora.
listRequests GET /requests Le tue richieste, dalla più recente. Filtra per modalità o stato; pagina con cursor.
updateRequest PATCH /requests/{id} Cambia il contenuto, aggiungi destinatari o imposta una nuova scadenza.
remind POST /requests/{id}/remind Manda per email il link a chi non ha ancora risposto.
closeRequest DELETE /requests/{id} Smetti di accettare risposte.

Moduli e approvazioni

Ogni richiesta ha un mode:

"form"
Raccogli dati. Invii uno schema; la persona riceve un modulo costruito a partire da quello e tu ottieni un oggetto che lo rispetta.
"approval"
Ottieni una decisione. Invii approval.reason; ogni persona riceve una scheda con Approva e Rifiuta (o le etichette che scegli tu) e un commento facoltativo. Ottieni ogni decisione e un verdict complessivo.

Entrambi accettano un title (fino a 120 caratteri), una riga requester facoltativa che dice chi sta chiedendo, un locale per la pagina e le sue email ("en", "es", "pt", "fr", "de", "it", "ja" o "zh", oppure con una regione come "es-AR" per le date) e metadata, che torna invariato in ogni webhook e stato. Scrivi il titolo e le domande nella stessa lingua.

Chi risponde

audience decide chi riceve un link.

kind Ottieni Usalo per
"named" links[], uno per persona in recipients (da 1 a 50, ciascuno { name, email?, phone? }) Risposte che devi poter attribuire a qualcuno. Le approvazioni devono essere nominative. Un’email abilita sendEmail, i promemoria e i codici via email.
"open" Un url che chiunque può aprire Iscrizioni e sondaggi. maxSubmissions limita le risposte (predefinito 1).

A cosa serve

Una modalità e un’audience coprono quasi tutto ciò che altrimenti faresti con un form builder, un sondaggio, un’app per gli appuntamenti o una catena di email.

Vuoi Richiesta
I dati di una persona: un indirizzo di spedizione, l’accoglienza di un cliente, una fascia di prenotazione "form", nominativo, un destinatario
Un sondaggio, una votazione, feedback o iscrizioni da chiunque "form", aperto con maxSubmissions. Pubblica l’unico url dove vuoi; getStatus restituisce tutte le risposte, così il tuo agente le riassume.
Conferme di partecipazione, disponibilità, sostituzioni di turno o check-in da un gruppo noto "form", nominativo (fino a 50), così ogni risposta è attribuita e remind sollecita chi manca
Approvazioni, via libera e votazioni "approval" con una policy; aggiungi verify: "email" per denaro, accessi o cancellazioni

Stato e scadenza

status Significa
pending Nessuno ha ancora risposto.
partial Alcune persone indicate hanno risposto, altre no.
complete Hanno risposto tutti, è stato raggiunto maxSubmissions, oppure un’approvazione ha il suo esito.
expired Il link è scaduto.
closed Hai chiamato closeRequest.

Scadenza. expiresIn accetta "30m", "48h", "7d" o secondi. Il valore predefinito è 7 giorni e il massimo 90.

Modificare una richiesta. updateRequest cambia titolo, schema, sezioni, motivo o tema finché non arriva la prima risposta. Aggiungere destinatari, impostare una nuova scadenza (contata da adesso) e cambiare notifyEmail funzionano finché la richiesta non è completata, scaduta o chiusa. Ai destinatari aggiunti non viene mandata un’email; invia tu i loro link oppure chiama remind con i loro recipientIds.

Promemoria. remind manda per email il link ai destinatari nominativi che non hanno risposto e hanno un’email, al massimo una volta ogni 24 ore ciascuno. L’email di sendEmail conta come la prima.

Ricevere la risposta. Usane uno o combinane diversi:

webhookUrl
Il tuo server riceve ogni risposta man mano che arriva. Vedi Webhook.
notifyEmail
Mandiamo al tuo account un riepilogo e un link alla richiesta nella dashboard: "each" a ogni risposta (finché non si raggiungono i limiti di email del piano, poi solo alla fine), oppure "complete" una sola volta quando si completa o scade. Le email delle approvazioni includono la decisione e il commento; le risposte dei moduli restano nella dashboard. Disattivato per impostazione predefinita; updateRequest può cambiarlo.
getStatus con wait
Tiene la chiamata aperta fino a 25 secondi (REST: ?wait=25) e risponde appena qualcuno risponde o lo stato cambia. Richiamala per continuare ad aspettare.
MCP push (Builder e Pro)
Ogni richiesta è la risorsa MCP runitby://requests/{requestId}, collegata da createRequest; leggerla restituisce lo stesso di getStatus. Su Builder e Pro, i client sul protocollo 2026-07-28 possono iscriversi con subscriptions/listen e ricevere notifications/resources/updated a ogni risposta o cambio di stato, con un’iscrizione aperta alla volta su Builder e fino a tre su Pro. Su Free subscriptions/listen risponde con un errore che indica gli altri modi per ricevere la risposta.

Schema del modulo

JSON Schema semplice con type: "object" in cima e fino a 40 campi. required[] viene applicato, e title e description diventano l’etichetta e il testo di aiuto.

Tipo Parole chiave
string format (email, date, time, date-time, tel, uri, duration), minLength, maxLength, pattern
number, integer minimum, maximum
boolean const: true crea una casella di consenso che va spuntata
enum Un elenco fisso di scelte
array Di primitivi o di un enum; minItems, maxItems

Suggerimenti. Metti le opzioni per campo in "x-runitby": widget, placeholder, help, columns (1 o 2), step e currency.

Sezioni. Raggruppa i campi con sections: [{ title, fields: [...] }] accanto allo schema.

Oggetti annidati (tranne il campo di posizione), oneOf, anyOf, allOf e $ref vengono rifiutati con un messaggio che dice cosa cambiare. I campi che chiedono password, PIN, numeri di carta, CVV, codici di sicurezza, codici fiscali o codici monouso vengono rifiutati.

Tipi di campo

Campi pronti per ciò che per le persone è scomodo da digitare. Ognuno è un normale JSON Schema più un widget, quindi la risposta viene validata come qualsiasi altro campo.

Campo Schema Risposta
Data string, format date "2026-11-12"
Ora string, format time; step = minuti (1–60) "14:30"
Data e ora string, format date-time "2026-11-12T14:30:00-08:00"
Durata string, format duration "PT1H30M"
Fasce orarie array di enum date-time, widget slots gli orari scelti
Intervallo di date array di 2 date, widget daterange ["2026-11-12", "2026-11-15"]
Posizione object, widget location { latitude, longitude, accuracy }
Importo number, currency "USD" 1200
Cursore, valutazione number o integer; il cursore richiede minimum e maximum 7
Chip, radio, select enum (chips accetta anche un array di enum) "M"
Classifica array di enum, widget rank tutte le opzioni, nell’ordine della persona
Sì o no boolean, widget yesno true
Colore string, widget color "#C2410C"
Paese string, widget country "US" (ISO 3166-1)
Lingua string, widget language "es-AR" (BCP 47)
Fuso orario string, widget timezone "America/New_York"

Aggiungi un enum a un campo paese o lingua per limitare le scelte.

Anteprima

previewRequest accetta gli stessi campi di modulo o approvazione di createRequest (senza audience, scadenza, webhook o metadata) e restituisce screenshot larghi 390 px e 1280 px, più lint[] con tutto ciò che si leggerà male. Non viene creato nulla.

Passa sampleData per vedere il modulo compilato e viewports per ottenere una sola dimensione. Fai prima l’anteprima quando lo stesso modulo verrà inviato molte volte.

Temi

theme fa sembrare la pagina il tuo prodotto. Senza, le pagine sono inchiostro su bianco caldo, Figtree con titoli in Fraunces, angoli arrotondati.

Chiave Valori
accent, background, surface, text Colori esadecimali
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 (tutti i campi in una pagina) o single (una domanda alla volta)
logoUrl Il tuo logo
heroText, thankYou Il saluto sopra il modulo e il messaggio dopo l’invio

Opzioni di approvazione

Le approvazioni richiedono un’audience nominativa: ogni persona riceve il proprio link, così ogni decisione le è attribuita. L’esito è "approved", "declined" oppure "expired" quando nessuno ha deciso in tempo; mai un sì silenzioso.

campo approval Predefinito Note
reasonobbligatorio Cosa stai chiedendo, fino a 300 caratteri.
detail Contesto sotto il motivo, fino a 1.000 caratteri.
policy "all" "any", "all", "majority" o { n }: quante approvazioni servono.
options Approva, Rifiuta Da due a quattro etichette; la prima conta come approvazione. Le decisioni tornano in snake_case: «Approva con modifiche» → "approve_with_changes".
allowComment true Permetti alle persone di aggiungere un commento alla loro decisione.
showOthers false "names" o "counts" mostra a ciascuno a che punto sono gli altri.
verify false "email": ogni persona conferma un codice di 6 cifre inviato al proprio indirizzo prima che i pulsanti funzionino, così un link inoltrato non può decidere al suo posto. Ogni destinatario deve avere un’email. Usalo per denaro, accessi o cancellazioni.

Webhook

Imposta webhookUrl (https) su una richiesta e ci facciamo un POST di JSON per due eventi:

response.created
Ogni invio o decisione, con la risposta in response.
request.completed
Ogni destinatario nominativo ha risposto, è stato raggiunto maxSubmissions, un’approvazione ha il suo esito oppure la richiesta è scaduta.

Verifica la firma. X-Runitby-Signature è l’HMAC-SHA256 esadecimale del corpo grezzo con il segreto di firma del tuo account, che trovi nella dashboard. X-Runitby-Timestamp è l’ora di invio in secondi Unix.

Nuovi tentativi. Qualsiasi 2xx entro 10 secondi conta come consegnato. Altrimenti riproviamo 4 volte, 1 min, 5 min, 30 min e 2 h dopo ogni fallimento. Dopo, la risposta resta comunque disponibile in getStatus.

Errori

Gli errori sono JSON con un message leggibile e, per gli input non validi, problems[] che indica ogni campo da cambiare. Di solito gli agenti riescono a correggere la richiesta dal solo messaggio.

Stato Quando
400 L’input o lo schema non è valido.
401 Chiave API mancante o revocata.
404 Nessuna richiesta con quell’id nel tuo account.
409 La modifica non è più consentita, per esempio modificare dopo la prima risposta o sollecitare una richiesta chiusa.
429 Oltre 60 creazioni al minuto, oppure le richieste mensili del piano sono esaurite.

Piani e limiti

Free Builder Pro
Richieste al mese 250 2,000 10,000
Risposte per link aperto 25 10,000 Illimitato
Chiavi API 1 5 Illimitato
App collegate (OAuth) 1 5 Illimitato
Risposte conservate dopo la consegna 30 giorni 90 giorni Conservate
Email al mese 500 4,000 20,000
Email per richiesta 10 10 10
MCP push (iscrizioni aperte) — 1 3
Prezzo al mese $0 $9 $29

Superato il limite mensile, createRequest restituisce 429 finché il periodo non si azzera o passi a un piano superiore (su Pro, il limite di uso corretto, scrivici per averne di più); i link già inviati continuano a funzionare. Senza un webhook, le risposte vengono conservate a partire dall’invio. Vedi i prezzi.

Le email che mandiamo per te (link, promemoria e aggiornamenti notifyEmail) contano per entrambi i limiti di email. Superato uno dei due, i link tornano come "limit" perché li mandi tu e gli aggiornamenti "each" si fermano. L’email che dice che una richiesta è finita parte sempre, e i codici di approvazione non contano.

Su ogni piano: 60 creazioni al minuto per chiave API, title fino a 120 caratteri, approval.reason 300, approval.detail 1.000 e metadata sotto i 4 KB.

Sei il titolare del trattamento di ciò che raccogli. Chiedi solo ciò che serve al compito.