Documentação
Pergunte a quem precisar a partir do seu agente.
Seu agente descreve o que precisa (um formulário, uma pesquisa ou um sim ou não) e recebe um link para uma pessoa, para cada pessoa de um grupo ou para qualquer um com quem você o compartilhar. As pessoas abrem no celular, sem cadastro, e as respostas voltam para você como JSON validado.
-
Crie uma solicitação. Chame
createRequestcom um JSON Schema para um formulário, ou com um motivo para uma aprovação. -
Envie o link. Passe
sendEmail: truee nós o enviamos por e-mail a cada pessoa nomeada, mande por um canal que você já tenha (e-mail, chat ou SMS) ou publique um link aberto onde quiser. -
Receba a resposta. No Builder e no Pro, seu cliente MCP recebe cada resposta por push assim que ela chega. Ela também chega ao seu webhook, por e-mail com
notifyEmail, ou você pode lê-la comgetStatus.
As mesmas ferramentas estão disponíveis de duas formas: um servidor MCP para agentes que falam MCP e uma API REST para todo o resto. Os agentes podem ler este guia em llms.txt.
Guia rápido
De uma chave de API à resposta de uma pessoa em quatro passos.
1Obtenha uma chave de API
Entre com seu e-mail e copie a chave do painel. Ela começa com sk_live_; mantenha-a no seu servidor. Usa Claude Code, Codex ou outro cliente MCP? Pule esta etapa: adicione o servidor pela URL e entre pelo cliente.
2Crie uma solicitação
Esta pede a Jordan um endereço de entrega e uma data de entrega. O schema é JSON Schema comum; veja Schema do formulário para saber o que é suportado.
3Envie o link
A resposta traz um link por pessoa em links[] (ou uma única url para um link aberto). Com "sendEmail": true, enviamos a cada pessoa nomeada que tenha e-mail o seu próprio link, em nome da sua conta. O email de cada link diz o que aconteceu: "sent", "failed" (a solicitação continua existindo; chame remind depois), "limit" (os limites de e-mail do plano foram atingidos), "no address" ou "off". Envie os demais como preferir: e-mail, chat ou SMS.
4Receba a resposta
Quando Jordan enviar, seu webhookUrl recebe um evento response.created com os dados, já conferidos com o seu schema. Sem webhook? Chame getStatus com o requestId, defina notifyEmail e avisamos você por e-mail quando tudo estiver concluído, ou, no Builder e no Pro, assine por MCP e seu agente é avisado assim que Jordan responder. Veja Receber a resposta.
Autenticação
Toda chamada MCP e REST envia uma chave de API como bearer token. A mesma chave serve para as duas. Uma chave ausente ou revogada recebe um 401. Há duas formas de obter uma.
Entre pelo seu cliente MCP
Adicione https://runitby.app/mcp sem chave e o cliente faz seu login por OAuth: abre um navegador, você informa seu e-mail e o link de login leva você a uma página que pede para permitir o app. É a primeira vez? O mesmo link cria sua conta. O app passa então a ter a própria chave, com o nome dele, que você pode revogar em Chaves.
-
Claude Code: execute o comando à direita, depois
/mcpno Claude Code e escolha autenticar. -
Codex: execute
codex mcp adde depoiscodex mcp login. - Claude (web e desktop): Configurações, Conectores, Adicionar conector personalizado, e cole a URL.
- Outros clientes com suporte à autorização MCP: adicione a URL sem cabeçalhos.
Crie uma chave no painel
Para a API REST, scripts e clientes que só aceitam um cabeçalho: crie e revogue chaves no painel e envie a chave no cabeçalho Authorization.
Os planos contam as duas coisas separadamente. O Free inclui uma chave e um app conectado, o Builder cinco de cada, e o Pro quantos você precisar.
Exemplos de um único arquivo com uma chave: Vercel AI SDK, Mastra, LangChain.js e o Claude Agent SDK.
Ferramentas e endpoints
Cada ferramenta MCP tem um endpoint REST com a mesma entrada e a mesma saída. A referência da API lista todos os campos.
| Ferramenta MCP | REST | O que faz |
|---|---|---|
createRequest |
POST /requests | Cria um formulário ou uma aprovação e devolve o(s) link(s), enviados por e-mail por você se pedir. |
previewRequest |
POST /requests/preview | Capturas de tela e lint do que a pessoa vai ver. Não cria nada. |
getStatus |
GET /requests/{id} | Status, veredito e todas as respostas até agora. |
listRequests |
GET /requests | Suas solicitações, das mais recentes para as mais antigas. Filtre por modo ou status; pagine com cursor. |
updateRequest |
PATCH /requests/{id} | Altera o conteúdo, adiciona destinatários ou define uma nova expiração. |
remind |
POST /requests/{id}/remind | Envia o link por e-mail a quem ainda não respondeu. |
closeRequest |
DELETE /requests/{id} | Para de aceitar respostas. |
Formulários e aprovações
Toda solicitação tem um mode:
"form"- Coletar dados. Você envia um
schema; a pessoa recebe um formulário montado a partir dele, e você recebe de volta um objeto que o respeita. "approval"- Obter uma decisão. Você envia
approval.reason; cada pessoa recebe um cartão com Aprovar e Recusar (ou seus próprios rótulos) e um comentário opcional. Você recebe cada decisão e umverdictgeral.
Ambos aceitam um title (até 120 caracteres), uma linha requester opcional dizendo quem está perguntando, um locale para a página e seus e-mails ("en", "es", "pt", "fr", "de", "it", "ja" ou "zh", ou com uma região como "es-AR" para as datas) e metadata, que volta intacto em todo webhook e status. Escreva o título e as perguntas no mesmo idioma.
Quem responde
audience decide quem recebe um link.
| kind | Você recebe | Use para |
|---|---|---|
"named" |
links[], um por pessoa em recipients (de 1 a 50, cada um { name, email?, phone? }) |
Respostas que você precisa atribuir a alguém. As aprovações precisam ser nomeadas. Um e-mail habilita sendEmail, lembretes e códigos por e-mail. |
"open" |
Uma url que qualquer pessoa pode abrir |
Inscrições e pesquisas. maxSubmissions limita as respostas (padrão 1). |
Para que usar
Um modo e um público cobrem quase tudo o que você faria com um criador de formulários, uma enquete, um app de agendamento ou uma cadeia de e-mails.
| Você quer | Solicitação |
|---|---|
| Dados de uma pessoa: um endereço de entrega, cadastro de cliente, um horário agendado | "form", nomeado, um destinatário |
| Uma pesquisa, enquete, feedback ou inscrições de qualquer pessoa |
"form", aberto com maxSubmissions. Publique a url única onde quiser; getStatus devolve todas as respostas para seu agente resumir. |
| Confirmações de presença, disponibilidade, cobertura de turnos ou check-ins de um grupo conhecido |
"form", nomeado (até 50), para que cada resposta tenha autoria e remind cobre quem falta |
| Aprovações, validações e votos |
"approval" com uma policy; adicione verify: "email" para dinheiro, acesso ou exclusão |
Status e expiração
| status | Significa |
|---|---|
pending |
Ninguém respondeu ainda. |
partial |
Algumas pessoas nomeadas responderam, outras não. |
complete |
Todos responderam, maxSubmissions foi atingido ou uma aprovação tem seu veredito. |
expired |
O link expirou. |
closed |
Você chamou closeRequest. |
Expiração. expiresIn aceita "30m", "48h", "7d" ou segundos. O padrão é 7 dias e o máximo, 90.
Alterar uma solicitação. updateRequest muda o título, o schema, as seções, o motivo ou o tema até chegar a primeira resposta. Adicionar destinatários, definir uma nova expiração (contada a partir de agora) e mudar notifyEmail funcionam até a solicitação ser concluída, expirar ou ser encerrada. Os destinatários adicionados não recebem e-mail; envie os links deles ou chame remind com os recipientIds deles.
Lembretes. remind envia o link por e-mail às pessoas nomeadas que ainda não responderam e têm e-mail, no máximo uma vez a cada 24 horas para cada uma. O e-mail de sendEmail conta como o primeiro.
Receber a resposta. Use uma opção ou combine várias:
webhookUrl- Seu servidor recebe cada resposta assim que ela acontece. Veja Webhooks.
notifyEmail- Enviamos à sua conta um e-mail com um resumo e um link para a solicitação no painel:
"each"a cada resposta (até atingir os limites de e-mail do plano, depois só quando ela termina), ou"complete"uma única vez quando ela é concluída ou expira. Os e-mails de aprovação incluem a decisão e o comentário; as respostas dos formulários ficam no painel. Desativado por padrão;updateRequestpode alterar isso. getStatuscomwait- Segura a chamada por até 25 segundos (REST:
?wait=25) e responde assim que alguém responde ou o status muda. Chame de novo para continuar esperando. - MCP push (Builder e Pro)
- Cada solicitação é o recurso MCP
runitby://requests/{requestId}, referenciado emcreateRequest; ler esse recurso devolve o mesmo quegetStatus. No Builder e no Pro, clientes no protocolo 2026-07-28 podem assinar comsubscriptions/listene recebernotifications/resources/updateda cada resposta ou mudança de status, com uma assinatura aberta por vez no Builder e até três no Pro. No Free,subscriptions/listenresponde com um erro que indica as outras formas de receber a resposta.
Schema do formulário
JSON Schema comum com type: "object" no topo e até 40 campos. required[] é aplicado, e title e description viram o rótulo e o texto de ajuda.
| Tipo | Palavras-chave |
|---|---|
string |
format (email, date, time, date-time, tel, uri, duration), minLength, maxLength, pattern
|
number, integer |
minimum, maximum |
boolean |
const: true cria uma caixa de consentimento que precisa ser marcada |
enum |
Uma lista fixa de opções |
array |
De primitivos ou de um enum; minItems, maxItems |
Dicas. Coloque as opções de cada campo em "x-runitby": widget, placeholder, help, columns (1 ou 2), step e currency.
Seções. Agrupe campos com sections: [{ title, fields: [...] }] ao lado do schema.
Objetos aninhados (exceto o campo de local), oneOf, anyOf, allOf e $ref são rejeitados com uma mensagem dizendo o que mudar. Campos que pedem senhas, PINs, números de cartão, CVVs, códigos de segurança, CPFs ou códigos de uso único são recusados.
Tipos de campo
Campos prontos para o que as pessoas acham chato de digitar. Cada um é JSON Schema comum mais um widget, então a resposta é validada como a de qualquer outro campo.
| Campo | Schema | Resposta |
|---|---|---|
| Data | string, format date | "2026-11-12" |
| Hora | string, format time; step = minutos (1–60) | "14:30" |
| Data e hora | string, format date-time | "2026-11-12T14:30:00-08:00" |
| Duração | string, format duration | "PT1H30M" |
| Horários | array de enum date-time, widget slots | os horários escolhidos |
| Intervalo de datas | array de 2 datas, widget daterange | ["2026-11-12", "2026-11-15"] |
| Local | object, widget location | { latitude, longitude, accuracy } |
| Valor em dinheiro | number, currency "USD" | 1200 |
| Controle deslizante, nota | number ou integer; slider exige minimum e maximum | 7 |
| Chips, radio, select | enum (chips também aceita um array de enum) | "M" |
| Ranking | array de enum, widget rank | todas as opções, na ordem da pessoa |
| Sim ou não | boolean, widget yesno | true |
| Cor | string, widget color | "#C2410C" |
| País | string, widget country | "US" (ISO 3166-1) |
| Idioma | string, widget language | "es-AR" (BCP 47) |
| Fuso horário | string, widget timezone | "America/New_York" |
Adicione um enum a um campo de país ou de idioma para limitar as opções.
Pré-visualização
previewRequest aceita os mesmos campos de formulário ou aprovação que createRequest (sem público, expiração, webhook nem metadata) e devolve capturas de tela com 390 px e 1280 px de largura, mais lint[] com tudo o que vai ficar ruim de ler. Nada é criado.
Passe sampleData para ver o formulário preenchido e viewports para obter só um tamanho. Faça a pré-visualização antes quando o mesmo formulário for enviado muitas vezes.
Temas
theme faz a página ter a cara do seu produto. Sem ele, as páginas são tinta sobre branco quente, Figtree com títulos em Fraunces e cantos arredondados.
| Chave | Valores |
|---|---|
accent, background, surface,
text
|
Cores em hex |
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 (todos os campos em uma página) ou single (uma pergunta por vez) |
logoUrl |
Seu logo |
heroText, thankYou |
A saudação acima do formulário e a mensagem depois do envio |
Opções de aprovação
As aprovações precisam de um público nomeado: cada pessoa recebe o próprio link, então cada decisão é atribuída a ela. O veredito é "approved", "declined" ou "expired" quando ninguém decidiu a tempo; nunca um sim silencioso.
| campo da aprovação | Padrão | Observações |
|---|---|---|
reasonobrigatório |
O que você está pedindo, até 300 caracteres. | |
detail |
Contexto abaixo do motivo, até 1.000 caracteres. | |
policy |
"all" |
"any", "all", "majority" ou { n }: quantas aprovações são necessárias. |
options |
Aprovar, Recusar | De dois a quatro rótulos; o primeiro conta como aprovação. As decisões voltam em snake_case: "Approve with changes" → "approve_with_changes". |
allowComment |
true | Permite que as pessoas adicionem um comentário à decisão. |
showOthers |
false |
"names" ou "counts" mostra a cada pessoa como os outros estão votando. |
verify |
false |
"email": cada pessoa confirma um código de 6 dígitos enviado ao próprio endereço antes de os botões funcionarem, então um link encaminhado não decide por ela. Todo destinatário precisa de e-mail. Use para dinheiro, acesso ou exclusão. |
Webhooks
Defina webhookUrl (https) em uma solicitação e enviamos um POST com JSON para ele em dois eventos:
response.created- Cada envio ou decisão, com a resposta em
response. request.completed- Todas as pessoas nomeadas responderam,
maxSubmissionsfoi atingido, uma aprovação tem seu veredito ou a solicitação expirou.
Verifique a assinatura. X-Runitby-Signature é o HMAC-SHA256 em hexadecimal do corpo bruto com o segredo de assinatura da sua conta, disponível no painel. X-Runitby-Timestamp é o horário do envio em segundos Unix.
Novas tentativas. Qualquer 2xx em até 10 segundos conta como entregue. Caso contrário, tentamos de novo 4 vezes, 1 min, 5 min, 30 min e 2 h depois de cada falha. Depois disso, a resposta continua disponível em getStatus.
Erros
Os erros são JSON com uma message legível e, para entradas inválidas, problems[] apontando cada campo a mudar. Os agentes costumam conseguir corrigir a solicitação só com a mensagem.
| Status | Quando |
|---|---|
400 |
A entrada ou o schema não é válido. |
401 |
Chave de API ausente ou revogada. |
404 |
Nenhuma solicitação com esse id na sua conta. |
409 |
A alteração não é mais permitida, por exemplo editar depois da primeira resposta ou enviar lembrete de uma solicitação encerrada. |
429 |
Mais de 60 criações por minuto, ou as solicitações mensais do plano acabaram. |
Planos e limites
| Free | Builder | Pro | |
|---|---|---|---|
| Solicitações por mês | 250 | 2,000 | 10,000 |
| Respostas por link aberto | 25 | 10,000 | Ilimitado |
| Chaves de API | 1 | 5 | Ilimitado |
| Apps conectados (OAuth) | 1 | 5 | Ilimitado |
| Respostas mantidas após a entrega | 30 dias | 90 dias | Mantidas |
| E-mails por mês | 500 | 4,000 | 20,000 |
| E-mails por solicitação | 10 | 10 | 10 |
| MCP push (assinaturas abertas) | — | 1 | 3 |
| Preço por mês | $0 | $9 | $29 |
Ao passar do limite mensal, createRequest devolve 429 até o período reiniciar ou você fazer upgrade (no Pro, o limite de uso justo; escreva para nós se precisar de mais); os links já enviados continuam funcionando. Sem webhook, as respostas são mantidas a partir do envio. Veja os preços.
Os e-mails que enviamos por você (links, lembretes e avisos de notifyEmail) contam para os dois limites de e-mail. Passando de qualquer um deles, os links voltam como "limit" para você mesmo enviar e os avisos "each" param. O e-mail que avisa que uma solicitação terminou sempre é enviado, e os códigos de aprovação não contam.
Em todos os planos: 60 criações por minuto por chave de API, title de até 120 caracteres, approval.reason de 300, approval.detail de 1.000 e metadata com menos de 4 KB.
Você é o controlador dos dados que coleta. Peça só o que a tarefa precisa.