| version | 1 |
| name | form-builder |
| description | Build stylish, Typeform-like multi-step forms and surveys using the Rebyte Forms library (Composer API). Outputs standalone HTML files. Triggers include "create a form", "build a survey", "make a questionnaire", "feedback form", "contact form", "signup form", "onboarding flow", "multi-step form", "typeform-style", "data collection form". Do NOT use for simple single-field inputs or backend form processing. |
Rebyte Forms Builder
Build production-ready, Typeform-style forms using the Composer API.
⚠️ CRITICAL: Completion Requirements
A form task is NOT complete until:
- ✅ Form backend created (POST /api/forms/create)
- ✅ HTML file saved as
index.html
- ✅ Invoke the
rebyte-app-builder skill to deploy the form
- ✅ BOTH URLs shared with user: Form URL (from deployment) AND Admin URL (from form creation API)
NEVER tell the user the form is "done" without completing ALL steps.
Requires Rebyte API auth — $AUTH_TOKEN and $API_URL are set up per the agent's system prompt; use them as Bearer token and base URL.
Boilerplate Template
<!DOCTYPE html>
<html lang="en" spellcheck="false" class="fmd-root" data-fmd-color-scheme="light">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{TITLE}}</title>
<link rel="stylesheet" type="text/css" href="https://unpkg.com/rebyte-forms@1.0.1/dist/css/formsmd.min.css">
</head>
<body class="fmd-body">
<noscript>Please turn on JavaScript to see this page.</noscript>
<div class="fmd-main">
<div class="fmd-main-container">
<div class="fmd-loader-container">
<div class="fmd-loader-spinner" role="status" aria-label="Loading"></div>
</div>
</div>
</div>
<script src="https://unpkg.com/rebyte-forms@1.0.1/dist/js/composer.bundle.min.js"></script>
<script src="https://unpkg.com/rebyte-forms@1.0.1/dist/js/formsmd.bundle.min.js"></script>
<script>
const composer = new Composer({
title: "{{TITLE}}",
colorScheme: "light",
accent: "#6366f1",
accentForeground: "#ffffff",
backgroundColor: "#fafafa",
color: "#18181b",
fontFamily: "Inter, sans-serif",
pageProgress: "show",
});
composer.startSlide({ buttonText: "Get Started" });
composer.h1("Welcome");
composer.p("Introduction text here.");
composer.endSlide();
composer.h1("Thank you!");
composer.p("Your response has been recorded.");
const formsmd = new Formsmd(composer.template, document, { isFullPage: true });
formsmd.init();
</script>
</body>
</html>
Composer Settings
| Setting | Type | Description |
|---|
title | string | Page title |
colorScheme | "light" | "dark" | Default color scheme |
accent | string | Primary color (hex) for buttons, fields |
accentForeground | string | Text color on accent background |
backgroundColor | string | Page background color |
color | string | Text color |
backgroundImage | string | CSS background-image (gradient or url) |
backdropOpacity | string | Overlay opacity on background image (e.g., "0.4") |
fontFamily | string | Font family |
fontSize | "sm" | "lg" | Font size |
rounded | "none" | "pill" | Button/UI rounding |
pageProgress | "hide" | "show" | "decorative" | Progress bar style |
formStyle | "classic" | Classic form field appearance |
postUrl | string | URL to POST form responses |
Field Types
Text Input
composer.textInput("fieldName", {
question: "What's your name?",
placeholder: "John Doe",
required: true,
description: "Optional helper text",
multiline: true,
maxlength: 500,
autofocus: true,
subfield: true,
});
Email Input
composer.emailInput("email", {
question: "Your email address?",
placeholder: "you@example.com",
required: true,
});
Phone Input
composer.telInput("phone", {
question: "Phone Number",
country: "US",
required: true,
});
URL Input
composer.urlInput("website", {
question: "Your website",
placeholder: "https://example.com",
});
Number Input
composer.numberInput("salary", {
question: "Expected salary (USD)",
placeholder: "100000",
unit: "$",
min: 50000,
max: 500000,
});
Choice Input (Radio/Checkbox)
composer.choiceInput("role", {
question: "What's your role?",
choices: ["Developer", "Designer", "Manager", "Other"],
required: true,
});
composer.choiceInput("ticket", {
question: "Select ticket type",
choices: [
{ label: "General - $99", value: "general" },
{ label: "VIP - $299", value: "vip" },
],
required: true,
});
composer.choiceInput("skills", {
question: "Select your skills",
description: "Choose all that apply",
choices: ["JavaScript", "Python", "Go", "Rust"],
multiple: true,
});
composer.choiceInput("size", {
question: "T-Shirt Size",
choices: ["S", "M", "L", "XL"],
horizontal: true,
});
Select Box (Dropdown)
composer.selectBox("country", {
question: "Select your country",
placeholder: "Choose one",
options: ["USA", "Canada", "UK", "Germany", "Other"],
});
Rating Input
composer.ratingInput("satisfaction", {
question: "How satisfied are you?",
outOf: 5,
icon: "star",
required: true,
});
Opinion Scale (NPS)
composer.opinionScale("nps", {
question: "How likely are you to recommend us?",
startAt: 0,
outOf: 10,
labelStart: "Not likely",
labelEnd: "Very likely",
required: true,
});
File Upload
composer.fileInput("resume", {
question: "Upload your resume",
description: "PDF format, max 10MB",
sizeLimit: 10,
required: true,
});
Date/Time Inputs
composer.dateInput("startDate", { question: "Start date" });
composer.timeInput("preferredTime", { question: "Preferred time" });
composer.datetimeInput("appointment", { question: "Select date and time" });
Slide Structure
composer.startSlide({ buttonText: "Begin" });
composer.h1("Title");
composer.p("Description");
composer.slide();
composer.textInput("name", { question: "Your name?", required: true });
composer.slide();
composer.h2("Contact Details");
composer.emailInput("email", { question: "Email", required: true });
composer.telInput("phone", { question: "Phone", subfield: true });
composer.endSlide();
composer.h1("Thanks!");
Conditional Display
Show a field only when a condition is met:
composer.choiceInput("wantFollowUp", {
question: "Can we follow up?",
choices: [
{ label: "Yes", value: "yes" },
{ label: "No", value: "no" },
],
});
composer.emailInput("followUpEmail", {
question: "Your email for follow-up",
displayCondition: {
dependencies: ["wantFollowUp"],
condition: "wantFollowUp == 'yes'",
},
});
Theme Presets
Light Professional
const composer = new Composer({
colorScheme: "light",
accent: "#18181b",
accentForeground: "#fafafa",
backgroundColor: "#fafafa",
color: "#18181b",
fontFamily: "DM Sans, sans-serif",
formStyle: "classic",
pageProgress: "show",
});
Dark Modern
const composer = new Composer({
colorScheme: "dark",
accent: "#a855f7",
accentForeground: "#ffffff",
backgroundColor: "#0f0a1e",
color: "#e2e8f0",
backgroundImage: "linear-gradient(135deg, #1a0a2e 0%, #16213e 50%, #0f0a1e 100%)",
fontFamily: "Space Grotesk, sans-serif",
rounded: "pill",
pageProgress: "show",
});
Warm Feedback
const composer = new Composer({
colorScheme: "light",
accent: "#f97316",
accentForeground: "#ffffff",
backgroundColor: "#fffbeb",
color: "#451a03",
backgroundImage: "linear-gradient(180deg, #fef3c7 0%, #fffbeb 50%, #fff7ed 100%)",
fontFamily: "Outfit, sans-serif",
fontSize: "lg",
pageProgress: "show",
});
With Background Image
const composer = new Composer({
colorScheme: "dark",
accent: "#f472b6",
accentForeground: "#ffffff",
backgroundColor: "#1e1b4b",
color: "#f8fafc",
backgroundImage: "url('https://images.unsplash.com/photo-xxx?w=1920&q=80')",
backdropOpacity: "0.4",
fontFamily: "Plus Jakarta Sans, sans-serif",
rounded: "pill",
});
Collecting Form Submissions
To collect responses, you need to:
- Create a form backend (stores submissions)
- Add
postUrl to your HTML form
- Save HTML as
index.html
- Invoke the
rebyte-app-builder skill to deploy
Complete Workflow
Step 1: Create Form Backend
Call the Forms API to create a backend that stores submissions:
curl -X POST "$API_URL/api/forms/create" \
-H "Authorization: Bearer $AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "My Survey",
"fields": ["name", "email", "rating", "feedback"]
}'
IMPORTANT: The fields array must contain the exact field names you use in your form (e.g., composer.textInput("name", ...) means "name" goes in fields).
Response:
{
"formId": "abc123def456",
"submitUrl": "https://.../api/forms/submit/abc123def456",
"adminUrl": "https://.../forms/abc123def456",
"fields": ["name", "email", "rating", "feedback"]
}
Save these URLs:
submitUrl: Where form data is POSTed (use as postUrl in Composer)
adminUrl: Spreadsheet UI to view all submissions (share with form creator)
Step 2: Configure Form HTML
Add the submitUrl as postUrl in your Composer settings:
const composer = new Composer({
title: "My Survey",
postUrl: "<submitUrl from API response>",
});
Step 3: Save and Deploy
- Save the form HTML as
index.html
- Invoke the
rebyte-app-builder skill to deploy it
- The skill will handle ZIP creation, upload, and deployment
Final URLs to Share
After deployment, you'll have:
- Form URL: From the
rebyte-app-builder skill output - Share with respondents
- Admin URL: From the form creation API response (Step 1) - View responses in spreadsheet
Viewing Results
Admin UI (Recommended): Open adminUrl in a browser to view responses in a spreadsheet interface with CSV/JSON export.
API Endpoints (for programmatic access):
- JSON:
GET $API_URL/api/forms/results/{formId}
- CSV:
GET $API_URL/api/forms/results/{formId}/csv
IMPORTANT: Always Return Both URLs
When you finish building and deploying a form, you MUST tell the user both URLs:
- Form URL (for respondents): From the
rebyte-app-builder skill output
- Admin URL (for viewing results): From the form creation API response (Step 1)
Never forget the Admin URL - without it, the user cannot see their form submissions!