Contact form monitoring dashboard showing form submission endpoint health, email queue status and CRM webhook delivery rate
# developer tools# website monitoring

How to Monitor Contact Forms and Lead Capture Forms

Contact forms and lead capture forms fail silently. When a checkout breaks, you see it in your revenue. When a login breaks, users tell you immediately. When a contact form breaks, leads just stop appearing — and you don't know if it's a broken form, a slow week, or a seasonal dip.

Broken forms have a particularly long detection lag because the failure mode is absence rather than error. No one reports getting an error message; they just never hear back from you.


What Can Break in a Contact Form

A contact form submission travels through several steps, any of which can fail:

  1. POST submission — the form data reaches your server (or doesn't)
  2. Validation and storage — the submission is written to your database or CRM
  3. Email notification — you receive an email alerting you to the new submission
  4. CRM/webhook delivery — the lead is pushed to HubSpot, Salesforce, Pipedrive, or a Zapier webhook
  5. Autoresponder — the user receives a confirmation email

Standard monitoring only covers step 1. Everything else is invisible without specific checks.


Health Check for Form Submission Flows

# Flask
@app.route('/health/forms')
def forms_health():
    checks = {}

    # 1. Test database write (can we store a submission?)
    try:
        db.execute('SELECT COUNT(*) FROM contact_submissions')
        checks['submission_db'] = 'ok'
    except Exception as e:
        checks['submission_db'] = f'error: {str(e)}'

    # 2. Test email notification queue
    queue_depth = get_queue_size('notifications')
    checks['notification_queue_depth'] = queue_depth
    checks['notification_queue'] = 'ok' if queue_depth < 200 else 'degraded'

    # 3. Test CRM webhook endpoint is reachable
    try:
        import requests
        resp = requests.post(
            os.environ['CRM_WEBHOOK_URL'],
            json={'test': True, 'source': 'health-check'},
            timeout=5
        )
        checks['crm_webhook'] = 'ok' if resp.status_code in [200, 201] else f'status: {resp.status_code}'
    except Exception as e:
        checks['crm_webhook'] = f'error: {str(e)}'

    all_ok = all(v == 'ok' for v in [
        checks.get('submission_db'),
        checks.get('notification_queue'),
        checks.get('crm_webhook'),
    ])

    return jsonify({'status': 'ok' if all_ok else 'degraded', **checks}), \
           200 if all_ok else 503
// Node.js
app.get('/health/forms', async (req, res) => {
    const checks = {};

    try {
        // DB write test
        await db.query('SELECT COUNT(*) FROM contact_submissions');
        checks.submissionDb = 'ok';

        // Email queue
        const queue = new Queue('notifications', { connection });
        const counts = await queue.getJobCounts('waiting');
        checks.notificationQueueDepth = counts.waiting;
        checks.notificationQueue = counts.waiting < 200 ? 'ok' : 'degraded';

        // CRM webhook test
        const crmResp = await fetch(process.env.CRM_WEBHOOK_URL, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ test: true }),
            signal: AbortSignal.timeout(5000),
        });
        checks.crmWebhook = crmResp.ok ? 'ok' : `status: ${crmResp.status}`;

        const allOk = ['submissionDb', 'notificationQueue', 'crmWebhook']
            .every(k => checks[k] === 'ok');

        res.status(allOk ? 200 : 503).json({ status: allOk ? 'ok' : 'degraded', ...checks });
    } catch (err) {
        res.status(503).json({ status: 'error', error: err.message, ...checks });
    }
});

Monitoring Third-Party Form Providers

If you use a third-party form tool — Typeform, HubSpot Forms, Formspree, Netlify Forms — the form itself is outside your direct control. What you can monitor:

The embed/script loading — If the third-party JS fails to load, your form may show as broken or invisible. Monitor that the form appears correctly by checking for the form element's presence.

The webhook/integration endpoint — Most form tools send a webhook to your server or CRM when a submission arrives. Monitor that endpoint:

# Your webhook receiver endpoint should respond to GET
curl -I https://yourdomain.com/webhooks/typeform

Submission notifications — If you receive email notifications for form submissions, a sudden gap in notifications (especially for high-traffic forms) is worth investigating.


Testing the Form Without Sending Fake Leads to Your CRM

A challenge with form monitoring: submitting a test form creates a fake lead in your CRM or inbox. Strategies to avoid this:

  1. Use a dedicated test email — create a monitored inbox ([email protected]) that receives test submissions. Alert if this inbox goes silent for more than 24 hours.

  2. Add a ?test=true parameter — handle this server-side to process the form without writing to your CRM or sending notifications.

  3. Monitor the stack components separately — rather than simulating a full form submission, test each component (DB, queue, webhook endpoint) independently via your health check.


The Lead Generation Cost of a Broken Form

For businesses running paid search or SEO campaigns, a broken contact form translates directly to wasted ad spend. Traffic arrives, intent is high, the form fails, the lead is lost. The campaign metrics look fine (traffic, clicks, time on page) but the conversion disappears.

Monitoring your form submission health endpoint gives you a signal that's independent of conversion rate fluctuations — a 503 is a broken form regardless of traffic volume.


Monitoring Forms with Domain Monitor

Domain Monitor monitors your /health/forms endpoint every minute. When your CRM webhook becomes unreachable, your notification queue backs up, or your database can't accept writes, you get an immediate alert — not a slow realisation weeks later that your lead flow has stopped. Create a free account.


Also in This Series

More posts

Wildcard vs SAN vs Single-Domain SSL Certificates: Which Do You Need?

Wildcard, SAN (multi-domain), and single-domain SSL certificates cover different use cases. Here's a clear comparison to help you pick the right type — and avoid paying for coverage you don't need.

Read more
Why DNS Works in One Location but Fails in Another

DNS resolves correctly from your office but fails for users in other countries or on different ISPs. Here's why geographic DNS inconsistency happens and how to diagnose which layer is causing it.

Read more
Registrar Lock vs Transfer Lock: What's the Difference?

Registrar lock and transfer lock are often confused — and disabling the wrong one leaves your domain vulnerable. Here's a clear breakdown of what each does and when to use them.

Read more

Subscribe to our PRO plan.

Looking to monitor your website and domains? Join our platform and start today.