O que você precisa saber
- Entenda para que serve o formulário, quem vai preencher e o que vai ser feito com as respostas.
create_form(ouget_form, para um formulário que já existe) retorna a definição completa e adraft_revisiondela.- Edite a definição completa e salve com
save_form_draft, enviando a revisão atual embase_revisione um UUIDv7 novo emmutation_id. - Confira os
issuesno retorno. Corrija e salve de novo até a lista ficar vazia. - Mostre o resultado ao usuário. Só chame
publish_formquando ele pedir, passando a revisão que ele conferiu.
Antes de começar
Pergunte ao usuário, ou descubra pela conversa:
- O objetivo. Para que decisão ou tarefa as respostas vão servir? Corte toda pergunta que não ajude nisso.
- Quem vai responder. Um cliente no celular, um colega, um convidado? Isso define o tom e o tamanho do formulário.
- O que é obrigatório. Torne obrigatórias só as respostas de que o usuário realmente precisa.
- O que acontece depois. A tela final deve dizer a quem responde o que esperar.
Se o formulário for longo ou tratar de um assunto sensível, liste as perguntas no chat e peça a confirmação do usuário antes de salvar.
Crie o formulário
Chame create_form com um nome. O form do retorno traz o id, a draft_revision (1 em um formulário novo), a definition e os issues atuais.
Todo formulário novo vem com uma tela de boas-vindas, uma pergunta de texto curto sem título, uma tela final de agradecimento e um tema branco. Os issues dele pedem o título que falta na pergunta. Troque essa pergunta inicial pela sua ou reaproveite o ID dela na sua primeira pergunta: nada depende dela ainda.
create_form não é idempotente. Se o retorno se perder, chame list_forms e procure o formulário antes de criar outro.
Para alterar um formulário que já existe, encontre-o com list_forms e leia com get_form.
Edite a definição
- Parta da definição que você acabou de ler. Mantenha todas as chaves principais, inclusive
schemaVersion,mediaDefaults,themeesettings, e todos os IDs existentes. Veja A definição do formulário. - Escreva as perguntas em
fields, na ordem em que vão aparecer para quem responde. Comece cada uma pelo modelo do tipo em Tipos de pergunta ou emlist_field_typese depois dê um título a ela. - Dê um ID novo a cada pergunta, opção, linha, regra e cálculo que você criar: um UUIDv7 em minúsculas, único no formulário. Se não conseguir gerar, chame
list_field_typescomid_counte use os IDs retornados. Detalhes em Identificadores. - Títulos e descrições são texto formatado, não strings simples. Veja Texto formatado.
- Para mudar o tipo de uma pergunta, substitua-a por uma nova, com ID novo, e atualize as regras, os cálculos e as referências de resposta que apontavam para o ID antigo.
- Use a configuração
nextButtonda última pergunta para dar ao botão um texto como "Enviar". Não existe um botão de envio separado.
Uma definição completa, pronta para publicar:
A referência técnica a seguir é gerada a partir do código e está em inglês, como os assistentes de IA a leem.
Contact request. The smallest useful form: three required questions, and an ending that greets the person by the name they typed.
It shows:
- required questions
- placeholder and maxLength settings
- an answer piped into the ending
Contact request definition
{
"schemaVersion": 2,
"mediaDefaults": {
"assetId": null,
"layout": "above",
"altText": ""
},
"welcome": {
"enabled": true,
"title": {"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"Get in touch"}]}]},
"description": {"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"Three quick questions. We reply within one working day."}]}]},
"button": "Start"
},
"ending": {
"title": {"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"Thanks, "},{"type":"answerToken","attrs":{"source":"answer","ref":"01990000-0000-7000-8000-000000000001","fallback":"there"}},{"type":"text","text":"!"}]}]},
"description": {"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"We will reply to your email within one working day."}]}]}
},
"fields": [
{
"id": "01990000-0000-7000-8000-000000000001",
"kind": "short_text",
"title": {"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"What is your name?"}]}]},
"description": {"type":"doc","content":[{"type":"paragraph","content":[]}]},
"required": true,
"options": [],
"rows": [],
"settings": {"nextButton":"Next","placeholder":"Jane Smith"},
"media": {"inherit":true,"assetId":null,"layout":"above"}
},
{
"id": "01990000-0000-7000-8000-000000000002",
"kind": "email",
"title": {"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"What is your email address?"}]}]},
"description": {"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"We only use it to reply to this message."}]}]},
"required": true,
"options": [],
"rows": [],
"settings": {"nextButton":"Next"},
"media": {"inherit":true,"assetId":null,"layout":"above"}
},
{
"id": "01990000-0000-7000-8000-000000000003",
"kind": "long_text",
"title": {"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"How can we help?"}]}]},
"description": {"type":"doc","content":[{"type":"paragraph","content":[]}]},
"required": true,
"options": [],
"rows": [],
"settings": {"nextButton":"Send message","maxLength":2000},
"media": {"inherit":true,"assetId":null,"layout":"above"}
}
],
"theme": {
"preset": "paper",
"background": "#ffffff",
"foreground": "#111827",
"primary": "#2563eb",
"buttonText": "#ffffff",
"font": "Inter",
"radius": 12,
"density": "comfortable",
"logoAssetId": null,
"backgroundAssetId": null
},
"settings": {
"allowReanswer": true,
"hiddenFields": [],
"fillLimit": null
},
"rules": [],
"calculations": []
}
Selecione o texto para copiá-lo.
Salve o rascunho
Chame save_form_draft com:
| Parâmetro | Valor |
|---|---|
form_id |
O ID do formulário. |
base_revision |
A última draft_revision que você leu, ou a revision retornada pelo seu último salvamento. |
mutation_id |
Um UUIDv7 novo a cada salvamento. |
name |
O nome completo do formulário. Uma string vazia salva o formulário com o nome padrão, "Untitled form". |
definition |
A definição completa, inclusive o que você não mudou. Um objeto parcial é recusado. |
O retorno traz a nova revision, os issues, o saved_at e o published_version_id. Use a revision como base_revision no próximo salvamento.
Se a rede falhar e você não souber se o salvamento passou, reenvie exatamente a mesma requisição, com o mesmo mutation_id. O trulyform devolve o resultado original em vez de salvar duas vezes. Já um mutation_id reaproveitado com outro conteúdo é recusado.
Quando o salvamento é recusado
validation_failedcomerrors: a definição está com o formato errado, por exemplo uma chave desconhecida, um ID inválido ou um título em string simples. Nada foi salvo. Corrija os caminhos indicados emerrorse salve de novo com a mesmabase_revisione ummutation_idnovo. As mensagens estão explicadas em Limites e erros.draft_conflict: existe um rascunho mais recente, talvez porque o usuário está editando o formulário no trulyform. Chameget_form, aplique sua alteração na definição retornada e salve com adraft_revisiondela. Nunca sobrescreva o rascunho mais recente com uma cópia antiga.
Corrija os problemas
O salvamento funciona mesmo que o formulário ainda não esteja pronto para publicar. Os issues do retorno listam o que ainda impede a publicação:
Um problema
{
"nodeId": "01990000-0000-7000-8000-000000000001",
"path": "title",
"message": "Write your question.",
"severity": "error"
}
Selecione o texto para copiá-lo.
nodeId é o ID da pergunta, regra ou cálculo com problema, ou então form, theme, welcome ou ending. Cada problema também tem um campo docs com a seção da documentação que o explica; passe esse valor para read_docs. Corrija todos os problemas e salve de novo. Os mais comuns estão em Problemas de publicação.
Revise com o usuário
Antes de publicar, resuma o formulário em linguagem simples: as perguntas em ordem, quais são obrigatórias e o que a lógica faz ("Se a pessoa escolher Presencial, perguntamos sobre restrições alimentares"). Passe ao usuário o editor_url do formulário, que vem em create_form, get_form ou list_forms. O link abre o formulário no editor do trulyform, onde ele pode pré-visualizar tudo exatamente como quem responde vai ver e fazer alterações por conta própria.
Publique
Chame publish_form com o form_id e a revision que o usuário conferiu, e só depois que ele pedir para publicar. O retorno traz a public_url para compartilhar.
- Se o rascunho mudou depois dessa revisão, a publicação falha com
draft_conflict. Antes, mostre o rascunho mais recente ao usuário. - Se o rascunho ainda tiver problemas, a publicação falha com
validation_failede a lista deissues. - Publicar de novo o mesmo conteúdo não cria uma versão nova.
- As respostas já recebidas continuam ligadas à versão em que foram respondidas.
- Um formulário fechado continua fechado. Para reabrir, o usuário usa Reabrir formulário no trulyform.
Dicas para um bom formulário
- Seja breve. A maioria dos formulários precisa de menos de dez perguntas. Cada pergunta a mais significa menos respostas.
- Uma ideia por pergunta, em linguagem simples. Texto de ajuda vai na descrição, não no título.
- Escolha o tipo certo para cada resposta. Use
emailpara e-mails,dropdownpara listas longas, como países,single_choicepara poucas opções,opinion_scaleounpspara avaliações econsentpara aceites. Uma respostanumberaceita decimais; para quantidades inteiras, como o número de convidados, use uma pergunta de escolha. - Use lógica em vez de perguntas do tipo "Se sim…", para que cada pessoa veja só o que vale para ela.
- Use a tela de boas-vindas para explicar para que serve o formulário e quanto tempo leva. Em formulários bem curtos, desative-a.
- Use a tela final para agradecer e dizer o que acontece depois. Chamar a pessoa pelo nome, com uma referência de resposta, deixa tudo mais pessoal.