One schema each. Nine very different forms.

From a three-field contact form to a full research survey — every form below is the real thing, embedded live from its /f/ page, theme and all. Submit one; it works. The single create_form call that built it sits on the left.

SIMPLE

Contact form

The classic three fields — and no theme block at all. This is what a formling form looks like out of the box: server-rendered, accessible, live in one POST.

short_textemaillong_text

View the schema — this is the entire build
POST /api/v1/forms
{
  "title": "Get in touch",
  "description": "Questions, ideas, bug reports — everything lands in one inbox.",
  "fields": [
    {
      "key": "name",
      "type": "short_text",
      "label": "Your name",
      "required": true,
      "placeholder": "Ada Lovelace"
    },
    {
      "key": "email",
      "type": "email",
      "label": "Email",
      "required": true,
      "placeholder": "ada@example.com"
    },
    {
      "key": "message",
      "type": "long_text",
      "label": "What's on your mind?",
      "required": true
    }
  ],
  "settings": {
    "submit_label": "Send message",
    "success_message": "Thanks — we read everything and reply within a day."
  }
}

EMAIL

Newsletter signup

An email capture that reads like a magazine: serif type, black accent, layout: plain strips the card chrome, and a little custom_css turns the title into a masthead rule with all-caps labels. Two fields, zero friction.

emailselect

View the schema — this is the entire build
POST /api/v1/forms
{
  "title": "The Sunday Letter",
  "description": "One essay on building calm software. No ads, unsubscribe anytime.",
  "fields": [
    {
      "key": "email",
      "type": "email",
      "label": "Email address",
      "required": true,
      "placeholder": "you@example.com"
    },
    {
      "key": "cadence",
      "type": "select",
      "label": "How often?",
      "display": "radio",
      "options": [
        "Every issue",
        "Monthly digest"
      ]
    }
  ],
  "theme": {
    "font": "serif",
    "colors": {
      "bg": "#ffffff",
      "card": "#ffffff",
      "text": "#1c1a15",
      "accent": "#1c1a15",
      "muted": "#6f695e"
    },
    "radius": "none",
    "layout": "plain",
    "custom_css": "[data-part=title]{border-top:3px solid var(--text);padding-top:1rem;font-size:2.1rem}.flabel{text-transform:uppercase;letter-spacing:0.12em;font-size:0.78rem}[data-part=submit]{border-radius:0}"
  },
  "settings": {
    "submit_label": "Subscribe",
    "success_message": "You're on the list — the next letter arrives Sunday."
  }
}

MARKETING

Launch waitlist

A landing-page waitlist in your own dark palette, pushed further with custom_css: a gradient-clipped title and a glowing submit button against the brand hooks. The hidden source field is set per visitor from the link — share ?source=launch-tweet and you have UTM tracking for free.

emailshort_textselecthiddencheckbox

View the schema — this is the entire build
POST /api/v1/forms
{
  "title": "Join the early access list",
  "description": "We onboard a new batch every Friday. Your spot is numbered.",
  "fields": [
    {
      "key": "email",
      "type": "email",
      "label": "Work email",
      "required": true,
      "placeholder": "you@company.com"
    },
    {
      "key": "company",
      "type": "short_text",
      "label": "Company",
      "placeholder": "Acme Corp"
    },
    {
      "key": "team_size",
      "type": "select",
      "label": "Team size",
      "options": [
        "Just me",
        "2–10",
        "11–50",
        "50+"
      ]
    },
    {
      "key": "source",
      "type": "hidden",
      "label": "Traffic source",
      "value": "direct"
    },
    {
      "key": "updates",
      "type": "checkbox",
      "label": "Email me ship-day updates"
    }
  ],
  "theme": {
    "font": "Space Grotesk",
    "colors": {
      "bg": "#0b0d12",
      "card": "#12151d",
      "text": "#f2f4f8",
      "accent": "#7aa2ff",
      "muted": "#8d97ad"
    },
    "radius": "xl",
    "custom_css": "[data-part=card]{background:linear-gradient(180deg,color-mix(in srgb,var(--accent) 7%,var(--card)),var(--card))}[data-part=title]{background:linear-gradient(90deg,var(--accent),#b69bff);-webkit-background-clip:text;background-clip:text;color:transparent}.choice{margin:0;border:1px solid var(--border)}.choice:has(input:checked){border-color:var(--accent)}[data-part=submit]{box-shadow:0 0 0 1px color-mix(in srgb,var(--accent) 45%,transparent),0 10px 34px -8px var(--accent)}"
  },
  "settings": {
    "submit_label": "Get my spot",
    "success_message": "You're in line. Watch your inbox on Friday."
  }
}

PRODUCT RESEARCH

NPS survey

The standard 0–10 scale with anchor labels, plus the one follow-up that matters. density: compact keeps it to a single screen; scores come back as numbers an agent can chart.

ratinglong_textemail

View the schema — this is the entire build
POST /api/v1/forms
{
  "title": "How are we doing?",
  "description": "One question, ten seconds. It shapes what we build next.",
  "fields": [
    {
      "key": "nps",
      "type": "rating",
      "label": "How likely are you to recommend us to a colleague?",
      "required": true,
      "min": 0,
      "max": 10,
      "labels": {
        "min": "Not likely",
        "max": "Extremely likely"
      }
    },
    {
      "key": "why",
      "type": "long_text",
      "label": "What's the main reason for your score?"
    },
    {
      "key": "email",
      "type": "email",
      "label": "Your email, if we may follow up"
    }
  ],
  "theme": {
    "font": "Inter",
    "colors": {
      "bg": "#f3f6f4",
      "card": "#ffffff",
      "text": "#15201a",
      "accent": "#2e9e5b",
      "muted": "#5f6f66"
    },
    "radius": "sm",
    "density": "compact"
  },
  "settings": {
    "submit_label": "Send score",
    "success_message": "Thank you — every score gets read."
  }
}

CUSTOMER FEEDBACK

Customer feedback

A rating, a category, an effort slider (with a value bubble that tracks the thumb) and a follow-up consent. A few custom_css rules turn the choice rows into bordered option cards. Answers arrive as numbers and booleans, so summarizing a week of feedback is one get_responses call away.

ratingselectnumberlong_textyes_no

View the schema — this is the entire build
POST /api/v1/forms
{
  "title": "Rate your experience",
  "description": "Two minutes, straight to the team.",
  "fields": [
    {
      "key": "score",
      "type": "rating",
      "label": "How was your experience overall?",
      "required": true,
      "min": 1,
      "max": 5,
      "labels": {
        "min": "Poor",
        "max": "Excellent"
      }
    },
    {
      "key": "area",
      "type": "select",
      "label": "What does this concern?",
      "options": [
        "Ordering",
        "Delivery",
        "Product quality",
        "Support"
      ]
    },
    {
      "key": "effort",
      "type": "number",
      "label": "How easy was it to get what you needed? (1 = hard, 10 = effortless)",
      "display": "slider",
      "min": 1,
      "max": 10,
      "step": 1
    },
    {
      "key": "details",
      "type": "long_text",
      "label": "Tell us more"
    },
    {
      "key": "followup",
      "type": "yes_no",
      "label": "May we contact you about this?"
    }
  ],
  "theme": {
    "font": "Atkinson Hyperlegible",
    "colors": {
      "bg": "#fbf8f1",
      "card": "#ffffff",
      "text": "#1c1a15",
      "accent": "#e8552f",
      "muted": "#6f695e"
    },
    "radius": "md",
    "custom_css": ".choice{margin:0;border:1px solid var(--border);background:var(--field-bg)}.choice:has(input:checked){border-color:var(--accent);background:var(--accent-soft)}[data-part=submit]{border-radius:999px}"
  },
  "settings": {
    "submit_label": "Send feedback",
    "success_message": "Thank you! Your feedback reaches the team within the hour."
  }
}

EVENTS

Party RSVP

Round corners, candy colors, an emoji in the title, and a dashed card from custom_css. yes_no, a headcount, an arrival time and dietary needs — everything a host needs. Add close_at or max_responses and it closes itself.

yes_nonumbertimemulti_selectshort_text

View the schema — this is the entire build
POST /api/v1/forms
{
  "title": "Midsummer rooftop party 🎈",
  "description": "Saturday June 27, 7pm — rooftop at HQ. Bring a friend or four.",
  "fields": [
    {
      "key": "attending",
      "type": "yes_no",
      "label": "Can you make it?",
      "required": true
    },
    {
      "key": "guests",
      "type": "number",
      "label": "How many guests are you bringing?",
      "min": 0,
      "max": 4,
      "step": 1
    },
    {
      "key": "arrival",
      "type": "time",
      "label": "Roughly what time will you arrive?"
    },
    {
      "key": "diet",
      "type": "multi_select",
      "label": "Any dietary needs in your group?",
      "options": [
        "Vegetarian",
        "Vegan",
        "Gluten-free",
        "Halal",
        "None"
      ]
    },
    {
      "key": "song",
      "type": "short_text",
      "label": "One song that has to be on the playlist",
      "placeholder": "artist — title"
    }
  ],
  "theme": {
    "font": "Baloo 2",
    "colors": {
      "bg": "#fff3f8",
      "card": "#fffdf3",
      "text": "#2b1c25",
      "accent": "#e069b8",
      "muted": "#8a6f7e"
    },
    "radius": "xl",
    "custom_css": "[data-part=card]{border:2px dashed color-mix(in srgb,var(--accent) 45%,var(--border))}.choice{margin:0;border:2px solid var(--border)}.choice:has(input:checked){border-color:var(--accent);background:var(--accent-soft)}[data-part=submit]{border-radius:999px}"
  },
  "settings": {
    "submit_label": "Send RSVP",
    "success_message": "Got it — see you on the rooftop! 🎉"
  }
}

ECOMMERCE

Merch pre-order

Picture choices — options that carry an image_url render as a visual grid instead of a dropdown. Pick a colourway, add bundles, choose a size and quantity, all heavily restyled with custom_css against the .pchoice and submit hooks.

short_textemailselectmulti_selectnumber

View the schema — this is the entire build
POST /api/v1/forms
{
  "title": "Pre-order the field kit",
  "description": "Ships in March. Reserve yours — pay nothing today.",
  "fields": [
    {
      "key": "name",
      "type": "short_text",
      "label": "Name",
      "required": true,
      "placeholder": "Ada Lovelace"
    },
    {
      "key": "email",
      "type": "email",
      "label": "Email",
      "required": true,
      "placeholder": "ada@example.com"
    },
    {
      "key": "colorway",
      "type": "select",
      "label": "Pick your colourway",
      "required": true,
      "options": [
        {
          "label": "Midnight",
          "image_url": "https://picsum.photos/seed/forma-midnight/400/300"
        },
        {
          "label": "Ember",
          "image_url": "https://picsum.photos/seed/forma-ember/400/300"
        },
        {
          "label": "Sage",
          "image_url": "https://picsum.photos/seed/forma-sage/400/300"
        }
      ]
    },
    {
      "key": "size",
      "type": "select",
      "label": "Size",
      "display": "radio",
      "options": [
        "S",
        "M",
        "L",
        "XL"
      ]
    },
    {
      "key": "addons",
      "type": "multi_select",
      "label": "Add a bundle",
      "options": [
        {
          "label": "Sticker pack",
          "image_url": "https://picsum.photos/seed/forma-stickers/400/300"
        },
        {
          "label": "Enamel pin",
          "image_url": "https://picsum.photos/seed/forma-pin/400/300"
        },
        {
          "label": "Tote bag",
          "image_url": "https://picsum.photos/seed/forma-tote/400/300"
        }
      ]
    },
    {
      "key": "qty",
      "type": "number",
      "label": "How many?",
      "min": 1,
      "max": 5,
      "step": 1
    }
  ],
  "theme": {
    "font": "Space Grotesk",
    "colors": {
      "bg": "#0e0f13",
      "card": "#16181f",
      "text": "#f3f5f8",
      "accent": "#f6c945",
      "muted": "#8b93a3"
    },
    "radius": "xl",
    "custom_css": "[data-part=title]{letter-spacing:-0.02em}.pchoice{background:var(--field-bg);transition:transform .16s,border-color .16s,box-shadow .16s}.pchoice:hover{transform:translateY(-3px)}.pchoice:has(input:checked){box-shadow:0 0 0 2px var(--accent),0 10px 30px -8px color-mix(in srgb,var(--accent) 60%,transparent)}[data-part=submit]{border-radius:999px;box-shadow:0 10px 30px -8px color-mix(in srgb,var(--accent) 65%,transparent)}"
  },
  "settings": {
    "submit_label": "Reserve my kit",
    "success_message": "Reserved! We'll email you the moment it ships."
  }
}

PRODUCT RESEARCH

Research survey

The serious survey toolbox in one schema: a statement intro, a satisfaction matrix, a full ranking, multi-select. Still one create_form call, still works without JavaScript.

statementselectmatrixrankingmulti_selectlong_text

View the schema — this is the entire build
POST /api/v1/forms
{
  "title": "Product research survey — Q3 roadmap",
  "description": "About 5 minutes. Your answers directly shape next quarter's priorities.",
  "fields": [
    {
      "key": "intro",
      "type": "statement",
      "label": "Answer for how you actually work",
      "body": "There are no wrong answers. Skip anything that doesn't apply — only the first two questions are required."
    },
    {
      "key": "role",
      "type": "select",
      "label": "What best describes your role?",
      "required": true,
      "options": [
        "Founder / executive",
        "Engineer",
        "Designer",
        "Product manager",
        "Other"
      ]
    },
    {
      "key": "frequency",
      "type": "select",
      "label": "How often do you use the product?",
      "required": true,
      "display": "radio",
      "options": [
        "Daily",
        "A few times a week",
        "Weekly",
        "Less than weekly"
      ]
    },
    {
      "key": "satisfaction",
      "type": "matrix",
      "label": "How satisfied are you with each area?",
      "rows": [
        "Speed",
        "Reliability",
        "Documentation",
        "Support"
      ],
      "columns": [
        "Unhappy",
        "Neutral",
        "Happy"
      ]
    },
    {
      "key": "priorities",
      "type": "ranking",
      "label": "Rank what we should build next",
      "options": [
        "Better integrations",
        "Mobile app",
        "Offline mode",
        "Team permissions"
      ]
    },
    {
      "key": "integrations",
      "type": "multi_select",
      "label": "Which tools should we integrate with first?",
      "options": [
        "Slack",
        "GitHub",
        "Linear",
        "Notion",
        "Zapier"
      ]
    },
    {
      "key": "magic_wand",
      "type": "long_text",
      "label": "If you could change one thing tomorrow, what would it be?"
    }
  ],
  "theme": {
    "font": "Fraunces",
    "colors": {
      "bg": "#f7f3ea",
      "card": "#fffdf8",
      "text": "#241f17",
      "accent": "#8a5a2b",
      "muted": "#7a715f"
    },
    "radius": "none",
    "custom_css": "[data-part=title]{font-style:italic}.matrix-wrap{border-width:2px}table.matrix thead th{letter-spacing:0.04em}[data-part=submit]{border-radius:0;letter-spacing:0.04em}"
  },
  "settings": {
    "submit_label": "Submit survey",
    "success_message": "Thank you — the results are tallied automatically."
  }
}

HIRING

Job application

A full intake pipeline: validated phone, URL and date fields, a structured address, and a consent checkbox that must be ticked. All validation is server-side — agents and humans get the same rules.

short_textemailphoneurladdressdatelong_textcheckbox

View the schema — this is the entire build
POST /api/v1/forms
{
  "title": "Senior product engineer — application",
  "description": "Remote, EU timezones. We reply to every application within a week.",
  "fields": [
    {
      "key": "name",
      "type": "short_text",
      "label": "Full name",
      "required": true
    },
    {
      "key": "email",
      "type": "email",
      "label": "Email",
      "required": true
    },
    {
      "key": "phone",
      "type": "phone",
      "label": "Phone"
    },
    {
      "key": "portfolio",
      "type": "url",
      "label": "Portfolio, GitHub or LinkedIn",
      "required": true
    },
    {
      "key": "location",
      "type": "address",
      "label": "Where are you based?"
    },
    {
      "key": "start",
      "type": "date",
      "label": "Earliest start date"
    },
    {
      "key": "pitch",
      "type": "long_text",
      "label": "Why you? A few sentences is plenty.",
      "required": true,
      "max_length": 1500
    },
    {
      "key": "consent",
      "type": "checkbox",
      "label": "I agree to my application data being processed for this role",
      "required": true
    }
  ],
  "theme": {
    "font": "IBM Plex Sans",
    "colors": {
      "bg": "#eef1f5",
      "card": "#ffffff",
      "text": "#161b22",
      "accent": "#0f62fe",
      "muted": "#5b6473"
    },
    "radius": "sm"
  },
  "settings": {
    "submit_label": "Submit application",
    "success_message": "Application received — you'll hear from a human within a week."
  }
}

Make one of these yours

Copy any schema into a curl — or skip the JSON entirely and just tell your agent “make me an RSVP form for Saturday”. It knows what to do.

curl -s -X POST https://formling.dev/api/v1/forms \
  -H "Content-Type: application/json" \
  -d @schema.json