Docs/Platform/Embedded forms

Embedded forms

Drop a working form for any endpoint onto your site with two lines of HTML — no backend, no key in the browser.

An embedded form is a generated, hosted form for a catalog endpoint that you paste into your own page. A visitor fills it in, it calls the API, and the result renders — with no backend of yours in the middle and, crucially, no API key in the browser.

It is the fastest way to put a lookup tool on a site: a VIN decoder on a dealership page, an email checker on a signup landing page, a currency converter in a help article.

PlanEmbedded forms
FreeNot included
StarterNot included
Pro10
Mega30

How it works

The form is served from forms.apiverve.com in an iframe and authenticates with a form token (avf_…), not your API key. Submissions are proxied server-side to the real endpoint using your key, which never reaches the page.

Three things happen between the visitor pressing submit and the answer appearing, and they are worth knowing because they explain the failure modes further down:

  1. The token is handed over out of band. It is never in the iframe URL. The frame announces itself when it loads, and the embed script posts the token to it — so the token is not in the page's address bar, in a referrer header, or in anything a proxy logged.
  2. The page proves which domain it is. The embed script signs the parent domain with a timestamp, and the server checks that signature against your allowed-domain list. A submission that did not come through the official embed script has no valid proof and is refused.
  3. The submission is proxied. The server attaches your API key, calls the endpoint, and returns the result to the frame. Your key is never on the client at any point.

That is the whole security argument for using this rather than calling the API from your own JavaScript. See CORS for why a browser-side key is a bad idea.

Setting one up

VerveKit → Embedded forms in the dashboard.

  1. Pick the endpoint. Search the catalog; the preview shows the form that endpoint generates from its published parameters, so required and optional fields are already right.
  2. Enable the form. That creates its token and unlocks the embed snippet.
  3. Configure it — see below.
  4. Copy the snippet into your page.

The fields come from the endpoint's schema, so nothing needs describing by hand and the form cannot drift from what the endpoint accepts. When an endpoint gains a parameter, the form gains the field.

The snippet

html
<div id="apiverve-form"
     data-api-id="emailvalidator"
     data-token="avf_your_form_token"
     data-captcha="true"
     data-layout="compact"
     data-color="light"
     data-primary="#0070f3">
</div>
<script src="https://forms.apiverve.com/embed.js"></script>

Two lines: a container and a script. No framework, no build step, nothing to install — it works in a static site, a CMS block or a landing page builder.

Only data-api-id and data-token are required. Everything else has a default.

AttributeDefault
data-api-idWhich endpoint the form callsrequired
data-tokenThe form token. Not your API keyrequired
data-captchaWhether the CAPTCHA is enforcedtrue
data-layoutcompact, standard or relaxed — how much room the fields getstandard
data-colorlight, dark or autoauto
data-primaryButtons and accents, as a hex colour#635bff
data-showjsonAdds a raw JSON tab to the result, for a developer audiencefalse
data-width100%, or a pixel value100%
data-heightauto, or a pixel valueauto
data-max-heightA ceiling for auto height; scrolls beyond itnone
data-param-*Pre-fills a field — data-param-email="a@b.com"none

Sizing

By default the frame resizes itself as the form does — a short form is short, and a long result does not sit in a scrollbox. The starting height is 400px and it grows from there, restoring your scroll position as it goes so the page does not jump under the reader.

Two ways to constrain it. data-max-height keeps auto-sizing but caps it, scrolling inside the frame beyond that point — the right choice for an endpoint whose results vary wildly in length. data-height="600" fixes the height outright and always scrolls, which is what you want in a layout that cannot tolerate a moving element.

Pre-filling fields

Any data-param-* attribute becomes a value in the form:

html
<div id="apiverve-form"
     data-api-id="currencyconverter"
     data-token="avf_your_form_token"
     data-param-from="USD"
     data-param-to="EUR">
</div>

Useful for a form that should start on a sensible default, and for a page that already knows part of the answer — a country page that pre-fills its own country, a docs page that pre-fills the example from the endpoint reference.

More than one form on a page

The script picks up every container whose id starts with apiverve-form, so give each one its own: apiverve-form-vin, apiverve-form-email. Ids have to be unique in a document anyway, and this is the naming that makes both forms initialise.

Single-page apps: load the script after the container exists

The embed script scans the page once, when the DOM is ready. A container that a framework renders later — after a route change, inside a component that mounts on demand — will not be found, and the console says as much: No form containers found.

In React, Vue or Svelte, render the div first and load embed.js after the component mounts, rather than putting the script tag in the document head.

Configuration that matters

Allowed domains

A comma-separated list of the domains this form may be embedded on. Domains, not URLs — the dashboard rejects anything with a scheme or a www. prefix and tells you so.

The rules, all enforced when you save:

  • Up to 10 domains, plus localhost, which does not count against the limit.
  • A dot is requiredexample.com, not example. localhost is the exception.
  • Wildcards are written *.example.com, which covers subdomains.
  • 500 characters total across the whole list.

This is the restriction that stops someone lifting your snippet onto their own site and spending your credits. Set it as soon as you know where the form lives, and include localhost while you are still building.

CAPTCHA

On by default, and the dashboard is blunt about why: Disabling CAPTCHA exposes your API key to bots. Only turn it off for internal sites you control.

The form is a path to your API key that anyone visiting the page can use. The CAPTCHA is what makes that path cost a human being's attention rather than a script's loop. Turn it off only for something behind your own authentication.

The domain list and the CAPTCHA solve different halves of the same problem: the list stops the form being used somewhere else, and the CAPTCHA stops it being used by something else on the page where it belongs. Neither substitutes for the other.

Appearance

Layout, colour scheme and primary colour, all previewed live. The defaults are neutral enough to sit on most sites; the primary colour is usually the only change worth making. auto follows the visitor's system theme, which is the right default for a page that has its own dark mode.

File uploads

Endpoints that take a file work here, and are one of the few places embedded forms do something the integration connectors cannot — those filter file-upload endpoints out of their dropdowns entirely. A form for an OCR or face-detection endpoint gets a real file picker and the upload is proxied through as multipart, with a longer timeout than an ordinary submission.

Worth remembering that those endpoints are also the ones with per-endpoint size limits, so check the reference page for the ceiling before you point visitors at one.

What it costs

Embedding is free. Submissions cost the endpoint's normal credits — one credit for most, more for the heavier ones, from the same monthly allowance as everything else. A form nobody submits costs nothing.

Two consequences worth planning around:

A public form is a public spend. Anyone who can load the page can spend a credit. The allowed-domains list and the CAPTCHA are what bound that, and they are worth getting right before you link to the page from anywhere popular.

Watch it like traffic. Analytics shows the endpoint's usage; a form on a page that unexpectedly does well shows up there first. The 80% usage alert in settings is worth leaving on for exactly this.

The forms key

Forms authenticate through a separate credential from your API key, and it can be rotated independently on the API keys page. Rotating your API key does not affect forms, and rotating the forms key does not affect your integration.

Rotating the forms key does invalidate embeds already on your pages, with no grace period — so if a form is embedded somewhere you cannot easily edit, that is a rotation to plan rather than do on impulse. Update the snippet everywhere first, then rotate.

Troubleshooting

Nothing renders and the console says no containers were found. The container did not exist when the script ran — see the single-page-app note above — or its id does not start with apiverve-form.

"Missing required attribute." Either data-api-id or data-token is absent. A templating system that strips unknown attributes is the usual culprit in a CMS.

The form renders but submissions fail. Almost always the domain list: the page's hostname is not on it, or it was entered as a URL and rejected at save time. Check the exact hostname the page is served on, including the subdomain.

It works locally and not in production. Same cause, one step later — localhost is on the list and the real domain is not.

Submissions fail after a key rotation. The snippet still carries the old token. Copy the current one from the dashboard.

Where forms fit

Good fits: a single-purpose lookup on a marketing page, a self-service checker in a help centre, a demo of what an endpoint returns, an internal tool nobody wants to build a UI for.

Not a fit: anything multi-step, anything that needs to store the submission, anything that needs to happen after the response (send an email, create a record), and anything that needs to combine two endpoints. A form calls one endpoint and shows you what came back. When you need more than that, call the API from your own backend — see making requests — or drive it from an integration platform that has somewhere to put the result.

Next

Mock endpoints and JSON bins are the other two VerveKit tools. CORS explains the browser constraint embedded forms exist to solve, and security covers the rest of the key-handling picture.

Was this page helpful?

Last updated