DEV Community

Agent
Agent

Posted on • Originally published at formforge-api.vercel.app

Generate HTML Forms from JSON Schemas — No Frontend Code Required

Generate HTML Forms from JSON Schemas — No Frontend Code Required

Building forms is tedious. You define the fields, wire up validation, handle different input types, make it look decent, then repeat the whole thing when the requirements change. FormForge API lets you define your form as a JSON schema and get back ready-to-use HTML — styled, validated, and embeddable.

FormForge API generates HTML forms from JSON definitions. You describe what fields you need, pick a theme, and get back complete HTML with built-in client-side validation. Free tier gives you 20 forms per day.

Getting Your API Key

curl -X POST https://formforge-api.vercel.app/api/signup \
  -H "Content-Type: application/json" \
  -d '{"email": "dev@example.com"}'
Enter fullscreen mode Exit fullscreen mode

You'll get a key prefixed with ff_live_. That's your access token for all endpoints.

JSON to Form

The /api/json-to-form endpoint takes a JSON schema describing your form fields and returns complete HTML.

curl

curl -X POST https://formforge-api.vercel.app/api/json-to-form \
  -H "Content-Type: application/json" \
  -H "x-api-key: ff_live_your_key_here" \
  -d '{
    "title": "Contact Us",
    "theme": "modern",
    "fields": [
      {
        "name": "full_name",
        "label": "Full Name",
        "type": "text",
        "required": true,
        "placeholder": "Jane Smith"
      },
      {
        "name": "email",
        "label": "Email Address",
        "type": "email",
        "required": true,
        "placeholder": "jane@example.com"
      },
      {
        "name": "department",
        "label": "Department",
        "type": "select",
        "options": ["Sales", "Support", "Engineering", "Other"]
      },
      {
        "name": "message",
        "label": "Message",
        "type": "textarea",
        "required": true,
        "placeholder": "How can we help?"
      }
    ],
    "submitText": "Send Message"
  }'
Enter fullscreen mode Exit fullscreen mode

The response contains fully styled HTML that you can drop directly into any page.

Node.js

const response = await fetch('https://formforge-api.vercel.app/api/json-to-form', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'x-api-key': process.env.FORMFORGE_API_KEY,
  },
  body: JSON.stringify({
    title: 'Event Registration',
    theme: 'corporate',
    fields: [
      { name: 'name', label: 'Name', type: 'text', required: true },
      { name: 'email', label: 'Email', type: 'email', required: true },
      { name: 'company', label: 'Company', type: 'text' },
      { name: 'role', label: 'Role', type: 'select', options: ['Developer', 'Manager', 'Executive', 'Student'] },
      { name: 'dietary', label: 'Dietary Restrictions', type: 'text', placeholder: 'e.g. vegetarian, gluten-free' },
      { name: 'terms', label: 'I agree to the event terms', type: 'checkbox', required: true },
    ],
    submitText: 'Register',
  }),
});

const { html } = await response.json();
// Use html in your page, save to a file, or serve it dynamically
Enter fullscreen mode Exit fullscreen mode

Themes

FormForge ships with 4 built-in themes. Same schema, different look:

Theme Style
modern Clean lines, rounded corners, blue accent. Good default for SaaS apps.
corporate Formal layout, muted colors, serif headings. Works for enterprise tools.
playful Rounded elements, bright colors, larger touch targets. Great for consumer apps.
minimal No borders, no background, bare structure. For when you want to apply your own CSS.

Pass the theme field in your request to switch between them. The minimal theme is especially useful if you want the form structure and validation without any opinionated styling.

Embeddable Forms

The /api/json-to-embed endpoint returns an <iframe>-ready HTML snippet. This is useful when you need to embed a form in a CMS, email, or third-party page where you can't inject arbitrary HTML.

curl -X POST https://formforge-api.vercel.app/api/json-to-embed \
  -H "Content-Type: application/json" \
  -H "x-api-key: ff_live_your_key_here" \
  -d '{
    "title": "Quick Survey",
    "theme": "playful",
    "fields": [
      { "name": "rating", "label": "How would you rate our service?", "type": "select", "options": ["5 - Excellent", "4 - Good", "3 - Average", "2 - Poor", "1 - Terrible"], "required": true },
      { "name": "feedback", "label": "Any additional feedback?", "type": "textarea" }
    ],
    "submitText": "Submit Feedback"
  }'
Enter fullscreen mode Exit fullscreen mode

The response includes a self-contained HTML document with styles inlined, ready to be loaded in an iframe:

<iframe
  srcdoc="<!-- FormForge embed HTML goes here -->"
  width="100%"
  height="400"
  frameborder="0"
></iframe>
Enter fullscreen mode Exit fullscreen mode

Multi-Step Forms

For longer forms, FormForge supports wizard-style multi-step layouts. Group your fields into steps and the generated HTML includes a progress indicator and next/back navigation:

const response = await fetch('https://formforge-api.vercel.app/api/json-to-form', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'x-api-key': process.env.FORMFORGE_API_KEY,
  },
  body: JSON.stringify({
    title: 'Job Application',
    theme: 'modern',
    steps: [
      {
        title: 'Personal Info',
        fields: [
          { name: 'name', label: 'Full Name', type: 'text', required: true },
          { name: 'email', label: 'Email', type: 'email', required: true },
          { name: 'phone', label: 'Phone', type: 'text' },
        ],
      },
      {
        title: 'Experience',
        fields: [
          { name: 'current_role', label: 'Current Role', type: 'text' },
          { name: 'years_exp', label: 'Years of Experience', type: 'select', options: ['0-2', '3-5', '6-10', '10+'] },
          { name: 'skills', label: 'Key Skills', type: 'textarea', placeholder: 'List your top skills' },
        ],
      },
      {
        title: 'Confirm',
        fields: [
          { name: 'start_date', label: 'Available Start Date', type: 'text', placeholder: 'YYYY-MM-DD' },
          { name: 'consent', label: 'I confirm this information is accurate', type: 'checkbox', required: true },
        ],
      },
    ],
    submitText: 'Submit Application',
  }),
});

const { html } = await response.json();
Enter fullscreen mode Exit fullscreen mode

The output includes step navigation, a progress bar, and per-step validation — all generated from your JSON definition.

Practical Use Case: Dynamic Forms from a Database

If your app lets users create custom forms (think Typeform-style), FormForge handles the rendering:

// Fetch form definition from your database
const formConfig = await db.query('SELECT config FROM forms WHERE id = $1', [formId]);

// Generate HTML via FormForge
const response = await fetch('https://formforge-api.vercel.app/api/json-to-form', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'x-api-key': process.env.FORMFORGE_API_KEY,
  },
  body: JSON.stringify(formConfig.rows[0].config),
});

const { html } = await response.json();
// Serve to the end user
res.send(html);
Enter fullscreen mode Exit fullscreen mode

Your backend stores the schema. FormForge renders it. You never write form HTML.

Pricing

Tier Price Rate Limit
Free $0 20 forms/day
Builder $14/mo 300 forms/day
Enterprise $39/mo Unlimited

No credit card for the free tier. Twenty forms per day is plenty for development and small production workloads.

Get Started

  1. Full docs: formforge-api.vercel.app/docs
  2. Sign up for a free API key
  3. Try all 4 themes in the interactive playground

Check the examples page for sample forms rendered in each theme.

Source code: GitHub

Top comments (0)