Bind your editable suburb input to city and its native suggestion list to localities. One clear API city fills automatically; otherwise the visitor chooses or types a suburb.
A choice fills only your bound city and state fields. The parse event keeps the API response in answer and the chosen suburb separately in selection. Keep manual entry available. This is geographic lookup, not mailing-address confirmation.
Built-in feedback in six languages. Pick one and try the example.
Language settings+
Page or form language
lang="es"
Form.js feedback only
data-parse-lang="es"
Switching language? Call parseform.scan(). Translate your labels and buttons as usual.
Familiar names. Stable codes.
Choose from 41 display languages and regional variants. Country names change for the reader; the country code stays the same.
More context. Fewer questions.
Optionally attach country, network, browser and device details to a submission.
More context with paid plans. Approximate city and region, VPN, Tor, relay and datacenter signals, plus richer browser and bot details. Unavailable values stay blank.
Paste these fields inside your form. Keep the outputs you need and use unique input ids.
Optional visit details · HTML
<!-- Visit details run once after someone starts filling out this form. --><!-- Deep data is included with paid plans. -->
<inputid="visit-ip"type="hidden"data-parse="ip"data-parse-deep="true">
<inputid="visit-useragent"type="hidden"data-parse="useragent"data-parse-deep="true">
<inputtype="hidden"name="ip"data-parse-fill="ip"data-parse-from="visit-ip">
<inputtype="hidden"name="ip_country"data-parse-fill="country"data-parse-from="visit-ip">
<inputtype="hidden"name="ip_asn"data-parse-fill="asn"data-parse-from="visit-ip">
<inputtype="hidden"name="ip_state"data-parse-fill="deep.state"data-parse-from="visit-ip">
<inputtype="hidden"name="ip_city"data-parse-fill="deep.city"data-parse-from="visit-ip">
<inputtype="hidden"name="ip_vpn"data-parse-fill="deep.vpn"data-parse-from="visit-ip">
<inputtype="hidden"name="ip_tor"data-parse-fill="deep.tor"data-parse-from="visit-ip">
<inputtype="hidden"name="ip_relay"data-parse-fill="deep.relay"data-parse-from="visit-ip">
<inputtype="hidden"name="ip_datacenter"data-parse-fill="deep.datacenter"data-parse-from="visit-ip">
<inputtype="hidden"name="device"data-parse-fill="device"data-parse-from="visit-useragent">
<inputtype="hidden"name="os"data-parse-fill="os"data-parse-from="visit-useragent">
<inputtype="hidden"name="browser"data-parse-fill="browser"data-parse-from="visit-useragent">
<inputtype="hidden"name="bot"data-parse-fill="bot"data-parse-from="visit-useragent">
<inputtype="hidden"name="bot_name"data-parse-fill="deep.bot.name"data-parse-from="visit-useragent">
Use context on your server+
For server decisions, look up context from the incoming request. Download the Node.js helper, set your secret PARSEAPI_KEY on the server, then call:
Get visitorIp from your framework's trusted proxy configuration, never a submitted hidden field or an unchecked forwarded header. Pass the request's User-Agent as userAgent; it is still client-controlled. Missing answers are null. Your backend decides what needs review.
Custom lookups fill your fields. Your existing validation decides what to accept.
Simple to start. Room to make it yours.
Keep the form you built. Add the help it was missing.
Your design.
Native controls and your CSS. Style the helpers or render results in your own components.
Your rules.
Keep required fields, schema validation and your submit handler. Choose which answers your business accepts.
Your stack.
Plain HTML or a framework. Attach new fields with parseform.scan() and respond to field events.
Ready for real people.
Keyboard-friendly suggestions and editable answers. Old results never replace newer input.
Choose what goes to your backend+
Your input's name is what your backend receives. data-parse-fill chooses the returned value; data-parse-from connects it to a source input. Use hidden inputs for extra details or visible, editable fields. Dotted keys read nested answers.
Your fields · HTML
<!-- Include form.js once, then add your own fields. -->
<inputid="billing-country"name="country"data-parse="/country/{code}"placeholder="US">
<inputtype="hidden"name="billing_currency"data-parse-from="billing-country"data-parse-fill="currency">
<inputtype="hidden"name="calling_code"data-parse-from="billing-country"data-parse-fill="calling_code">
Without data-parse-from, an output uses the preceding marked input. Keep input ids unique. Missing answers stay empty; browser-filled fields remain client-controlled.
Use your design and validation rules+
Form adds no stylesheet or inline styles. Style the default helpers with .parse-hint, .parse-hint-suggestion and .parse-address-suggestions. Use data-parse-status and data-parse-reason for field states.
For your own components, set data-parse-ui="none". To own validation too, set data-parse-validation="manual". Native HTML rules still apply. Set these options before attachment.
Custom UI · HTML
<!-- Include form.js once. Your markup, CSS, and messages. -->
<inputid="contact-email"type="email"name="email"data-parse="email"data-parse-ui="none"data-parse-validation="manual"aria-describedby="email-help">
<pid="email-help"role="status"></p>
<buttonid="email-correction"type="button"hidden></button>
<script>
const email = document.getElementById("contact-email");
const help = document.getElementById("email-help");
const correction = document.getElementById("email-correction");
const copy = {
invalid: "Check the email format.",
domain_invalid: "Check the domain after @.",
disposable: "Use an email you plan to keep.",
unavailable: "Email check unavailable. You can still send the form."
};
email.addEventListener("parse", ({ detail }) => {
const invalid = ["invalid", "disposable"].includes(detail.status);
const message = copy[detail.reason] ?? detail.message ?? "";
help.textContent = message;
email.setCustomValidity(invalid ? message : "");
email.setAttribute("aria-invalid", String(invalid));
correction.hidden = !detail.suggestions.length;
correction.textContent = detail.suggestions[0]?.label ?? "";
correction.onclick = () => detail.select?.(0);
});
</script>
The bubbling parse event returns status, value, answer, reason, message, suggestions and select(index). Your UI owns focus, keyboard interaction and accessibility. Stale selections are ignored after edits.
Use dynamic or framework forms+
Include the script once. Call parseform.scan() after mounting new inputs; existing fields stay attached once. With controlled inputs, keep your framework state in sync with input and change events, or handle the parse event in your own components.
Keep unique input ids across forms. Editing a source clears its old generated answers, and stale requests cannot overwrite newer input. Manual corrections remain yours.
Frequently asked questions.
Getting started
Start with the form you have.
What do I need to add form.js?+
Include the script once, add data-parse to the inputs you want to enhance, and supply a public ParseAPI key for your website. Your existing form, field names and submit handler stay in place.
The installation starter prepares the code for your site. Complete Newsletter, Contact and Checkout examples include the extra fields that receive returned data.
Will it work with my website or form builder?+
Form works with ordinary HTML inputs. You need a way to include JavaScript on the page and add attributes to the actual form controls. A builder that lets you edit both can use the same integration.
Check your builder's restrictions on scripts, custom attributes and embedded forms. Form does not automatically connect to every builder or reach inputs inside another site's iframe. Test the completed form at your submission destination.
Can I keep React, my schema and my validation library?+
Yes. Keep your form state, schema and business rules. Form adds field assistance and ParseAPI results; your library can decide how to display and accept them.
For dynamically mounted inputs, call parseform.scan() after mounting. Controlled inputs must keep framework state in sync with input and change events, or consume Form's parse event in your own components. See framework integration and custom validation.
How do the extra details reach my backend?+
You choose the fields and their names. Bind returned values to visible or hidden inputs, and they travel with the rest of your form through its normal submission. For example, one full-name input can fill separate first-name and last-name fields.
Form does not create a new submission destination. Missing answers leave generated outputs empty. The field bindings show how to use the names your backend already expects.
Can I use it for more than contact details?+
Yes. The same script supports fields such as postal codes, countries, cities, measurements, NPI, VIN and IBAN. Supported custom API paths can fill additional details into fields you define.
Choose the field for the job: a format or checksum result, a matching record and a selected suggestion have different meanings. Try the live field examples and browse the complete lookup catalog.
Checks and coverage
Know what each answer means.
What does the email check tell me?+
Form gives local guidance for incomplete input, then asks the Email API about email format, the domain's mail routing and disposable status. It can offer a typo correction for the visitor to select. Returned domain details can also fill your own fields.
A passing result does not prove that the mailbox exists, that a message will arrive or that the visitor owns it. Run any mailbox verification you need on your backend after submission; Form does not run that metered check while someone types.
Does it handle international phone numbers?+
Numbers beginning with + carry their own country calling code. To accept national numbers, supply explicit country context, such as data-parse-country="US". Form never guesses a phone number's country from the visitor's IP address.
The Phone API parses, checks numbering-plan validity and returns standardized formats. That does not establish whether a number is active, can receive a message or belongs to the person entering it. See the Phone reference.
What about international names or people with one name?+
Name parsing supports Unicode letters and single-word names. A single name can produce a first-name value with no last name; keep that possibility in your form and backend instead of requiring a surname from the parser.
Parsing uses first-name-first order unless a comma explicitly marks the surname. It cannot reliably infer every naming convention or establish someone's identity. Keep names editable and use your own acceptance policy where needed. Name reference
Which addresses can it suggest?+
Address autocomplete offers US address suggestions. Enter enough of the street and location, then select a suggestion to fill the connected street, city, state and ZIP fields. People can still enter an address manually and add an apartment or suite.
A selected match helps complete the form; it does not confirm deliverability or verify an apartment. Postal-code and city lookups have their own coverage. See the Address and Postal references.
Which languages does the feedback support?+
Built-in messages support English, Spanish, French, German, Brazilian Portuguese and Japanese. Form can follow your page or field language, with an explicit override when needed. Your labels, buttons and custom messages remain yours to translate.
The language of returned display labels is a separate setting, as are name-formatting rules. Changing feedback language does not change the submitted values. Try the language examples.
Behavior and control
Your form keeps the final say.
How quickly do checks happen?+
Local email and phone hints need no request. They appear after the visitor leaves a field and update during correction. API checks start when input is ready, after a short pause in typing, and results arrive as requests complete.
You can measure this browser's connection below. This tests the IP endpoint, not a complete field check; typing pauses and other lookups add time. Worldwide speed and status
From your browser
Five requests to /ip. Full response time, including the body and any connection setup.
Does Form work offline?+
Once the script has loaded, its local email and phone readiness hints can run without a network request or API key. They explain incomplete input or missing phone-country context; they are not a verified result.
API checks, formatting and returned data still need a connection to ParseAPI. Form is not a complete offline validation engine, and loading the hosted script also needs a connection unless your site has already made it available. An unavailable lookup adds no submission block.
What can stop someone submitting the form?+
By default, an API result marked invalid or disposable adds a native browser validation error. Required fields, input types and your existing validation continue to apply. Local readiness hints leave the field unchecked and add no new block.
A failed request, missing key, malformed response or timeout adds no block. Form never waits for a pending lookup before submission. The same applies if the script fails to load: your form's own submission and validation remain in charge.
Can I allow disposable email or use my own messages?+
Yes. Manual validation lets your application decide which results to accept, including disposable email. It leaves your native HTML rules and existing validators in place.
You can style Form's built-in helpers or turn them off and build your own interface from its events. Set these options before the fields attach. The UI and validation controls show how; custom interfaces also own their keyboard and accessibility behavior.
Will suggestions overwrite what someone has entered?+
Email typo corrections and address suggestions are applied when the visitor selects them. Returned details fill the fields you have explicitly connected. Those fields remain editable.
Form ignores stale results after the source changes and protects edits made while a request is pending. Changing a source clears its previous generated answers so details from an old value do not remain attached to a new one.
Plans and privacy
Understand the requests behind the fields.
Can I start on Free?+
Yes. Local email and phone readiness hints work without a key. API checks and returned core data use your public key and the pooled request allowance of your existing ParseAPI plan, including Free. There is no separate Form subscription.
Usage comes from API requests, not completed form submissions. A form with several marked fields can make several requests, and editing a value can trigger another check. The script waits for ready input and a typing pause; local hints do not use API requests.
Form supports included lookups and eligible deep enrichment. Metered mailbox, carrier and similar checks belong on your backend after submission; the script does not run them while a visitor types.
Is the API key meant to be visible in the browser?+
Yes: use a public key, restricted to your website's allowed domains. Public keys are designed for browser use and are visible in the page. Form refuses secret keys.
The setup flow prepares a public key for your site and its subdomains. Use a localhost allowance for local testing, and manage allowed domains or revoke keys in API keys. Keep your secret server key on your server.
What data is sent to ParseAPI?+
Configured field values and their lookup context are sent to ParseAPI for the requested checks. For example, a phone lookup can include its configured country. Your complete form submission goes through your existing backend or form destination.
IP and browser enrichment is a separate opt-in. When enabled for a form, those lookups run after its first non-empty edit, rather than on page load or focus. See optional visit details, the Privacy Policy and Security.
Can my backend trust a hidden field or a passing status?+
All browser values remain editable by the client, including hidden inputs and Form's status attributes. Use them to assist the visitor and carry useful details; validate the data your backend relies on before making an acceptance or security decision.
When a server decision needs fresh API evidence, request it on the server with your secret key. For visitor context, use the incoming request and trusted proxy configuration; a submitted IP field is not proof of the connection. The server example shows that boundary.
One script. A better form.
Start with the fields you have. Free includes 100k API requests a month.