Auto-Mode (easiest)


Will automatically find all forms on your page that have an email element, and attempt to verify them. Email elements are:

  • an <input> with a type="email" (Warning: IE does not support this!)
  • an <input> with a name="email"
  • an <input> with an id="email"

The associated form, will have any and all submit buttons disabled until the email field is marked as valid. Submit buttons are:

  • an <input> with a type="submit"
  • a <button> with a type that is not"button" nor "reset"

The result of the above function will be an array of goodforms objects (as explained in the section below)

If you do not want all forms on your page to be treated this way, or the script cannot find your form or submit button or email field, you need to use the more explicit instantiation, in the section below.

Once the email is considered ‘valid’, the form will be submitted normally with two additional fields -

goodforms_checksum will be set to a string with the verification checksum.

goodforms_status will be set to the extended ‘status’ of the email - valid, unknown, or catchall. It is not possible to submit an invalid email address (that’s kinda the point).

You can inspect the checksum to determine whether or not the email was legitimately verified by using the certify API - details in

Explicit Mode

var my_verifier = goodforms('form_key', {
    email_field: document.getElementById('your_email_dom_element'), 
    form: document.getElementById('your form element'),
    submit_button: document.getElementById('your_submit_button'), // you may also pass an ARRAY of submit buttons instead
    debug: true, //defaults to false, adds additional debugging output to javascript console
    onGood: function () {},
    onBad: function () {},
    onChallenge: function () {},
    onError: function () {},
    timeout: 10, // number of seconds to wait for response, default '10'
    visuals: true, 
    /* true or false for "all on" or "all off," or a JS object like: 
      {good: true, challenge: true, bad: true} to toggle individual 
      visualizations. Missing keys will default to 'true' meaning those 
      visualizations will occur when the appropriate states change */
    manual: true, //if set, NONE of the standard behavior will ever be invoked. Verification can only be invoked manually. See below.
    css: false, // FIXME - not yet implemented (and not sure if we should!)
}) //FIXME - should ensure that if you pass anything unexpected, it errors and doesn't silently accept it. Will reduce support.

Please note that in order to attach to multiple forms, the function must be invoked once per email address field.

If you do not wish for your submit buttons to be affected, you may set submit_button to false

The callback functions will fire before the default behaviors of the script are invoked.

If the script returns EXACTLY true, those behaviors will still fire normally. It must not return 1 or anything else that may evaluate to true in Javascript; it needs to explicitly be true.

If the script returns false, those behaviors will be cancelled. It must not return 0 or "" or null or anything else; it needs to be explicitly false.

If the script instead returns a function, that function will be invoked with a callback. If that function fires the callback, the normal behaviors will be triggered at that time. To prevent those behaviors, simply do not execute the callback.

Any other returned types from the functions will be considered an error.

Manual Mode

var my_verifier = goodforms('form_key', {
manual: true,
debug: true, //defaults to false, adds additional debugging output to javascript console


my_verifier.verify(address, callback (results) {


Event Flow

if you set an onSubmit handler in the form, that will fire first, before any goodforms handlers fire. If your handler returns false, the goodforms handlers will not be invoked.

If you set an onGood, onBad, etc. handler, those will be fired before the goodforms handlers fire. If your handler returns false, the goodforms handlers will not be invoked. 

If you need to do something asynchronously, return a function()instead, and that function will be passed a callback to the normal goodforms handling code. 

If your asynchronous callback is succesful, invoke the callback we passed you. If it is not, simply don’t call the callback at all.

If you invoke a raw .verify(address, callback) call, that callback will fire after the onGood, onBad, etc. handlers have fired. If you want to interrupt those handlers’ actions, you should instead attach callbacks to onGood, onBad, etc.