Contact Form Finder: Website Contact Pages & Forms avatar

Contact Form Finder: Website Contact Pages & Forms

Pricing

from $2.00 / 1,000 contact pages

Go to Apify Store
Contact Form Finder: Website Contact Pages & Forms

Contact Form Finder: Website Contact Pages & Forms

Find the contact page and visible enquiry form on company websites. Return the exact page, form type and evidence. Distinguish contact forms from search, signup and newsletter forms. No emails, personal details or form submissions.

Pricing

from $2.00 / 1,000 contact pages

Rating

0.0

(0)

Developer

Zaiq

Zaiq

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Share

Find a website's public contact page and check its HTML for an enquiry form. Each result includes the exact page, a plain verdict, visible field names, the pages checked and an observation time.

$0.002 per completed contact-page assessment ($2 per 1,000) on every Apify plan. A confirmed contact page with no observed enquiry form is also charged. Unresolved JavaScript forms, blocks, missing pages and invalid inputs return free notes. There is no custom startup or per-page fee.

Use the ready-to-run Console prefill for a one-site demonstration. The example below is a captured result with the source address replaced; replace example domains in API examples with your own public website URLs.

What you get

FieldWhat it holds
verdictA sentence stating what the checked HTML supports.
recordType, resultIdAssessment or free note; a stable ID from the normalized input hostname.
website, contactPageUrl, contactPageFoundInput website and confirmed contact-page address. Null means no confirmed page.
formStatepresent, not-observed or unknown-js. Null means assessment did not reach a form decision.
formType, formProviderinline, embedded or unknown; a provider only when an embed reference identifies it.
evidenceA generic contact heading label, selected visible labels and field names. No hidden fields, entered values or personal details.
checkedPagesPages assessed, HTTP status when available, outcomes and limitations.
coverageCompleteThe selected page's static assessment completed. This never means every page or JavaScript form on the website was checked.
status, note, sourceUrl, observedAtComplete, partial, blocked, invalid or no-match; explanation, source and UTC observation time.

What people use it for

  • Website routing: Find the enquiry page for a list of supplied company domains.
  • Contact-form inventory: Separate static enquiry forms from newsletter, search and account forms.
  • Recurring checks: Schedule a new run for the same websites and compare page addresses and form states over time.

How to use it

  1. Try the Console prefill, or enter up to 100 public domains or contact-page URLs.
  2. Choose up to three pages per site and any additional contact-link languages.
  3. Set the application spending limit and Apify's maximum run cost. The lower available limit controls new source work.
  4. Open the Contact pages table. Read free notes as well as completed assessments.

Input

FieldExampleNotes
urls["https://www.example.org/contact/"]Bare domains and HTTP(S) page URLs; up to 100 entries. API aliases: url and startUrls (strings or objects with url).
maxResults101–100 unique input sites, including sites returning free notes.
maxPagesPerSite21–3 HTML pages. Redirects and robots checks share the hard site budget.
languages["en", "de", "fr", "es"]English by default. These are link hints, not translation; the page's declared language adds its hints.
respectRobotsTxttrueAlways required. False returns a free input note.
maxChargeUsd0.01Application limit in USD; zero makes no website requests. Apify's spending limit also applies.

Output

Each result is one row in the run's dataset (download it as JSON, CSV, Excel, XML or HTML, or read it through the API). An example row (values shortened):

{
"verdict": "An enquiry form is visible in the contact page's HTML.",
"recordType": "assessment",
"resultId": "site-example.org",
"website": "https://www.example.org/contact/",
"contactPageUrl": "https://www.example.org/contact/",
"contactPageFound": true,
"formState": "present",
"formType": "inline",
"formProvider": null,
"evidence": {
"pageLabel": "contact",
"visibleLabels": [
"Name",
"E-mail",
"Your message"
],
"fieldNames": [
"name",
"email",
"message_subject",
"body"
],
"basis": "visible-form-controls"
},
"checkedPages": [
{
"url": "https://www.example.org/contact/",
"status": 200,
"outcome": "checked",
"formState": "present"
}
],
"coverageComplete": true,
"note": "Static HTML assessment of the selected page; scripts, stylesheets and embedded pages were not executed or fetched. This is not an exhaustive website crawl.",
"status": "complete",
"sourceUrl": "https://www.example.org/contact/",
"observedAt": "2026-10-25T12:24:16Z"
}

This row comes from a real free local test on 25 October 2026. Site addresses and the domain-based result ID were replaced with example.org; the /contact/ path replaces the source's contact-page path. No real person, account or handle was included. SUMMARY records newly delivered assessments, free notes, duplicate inputs, skipped work, source failures, limits and previously delivered rows skipped after a restart.

Pricing

  • $0.002 per completed contact-page assessment, once per normalized input hostname in a run.
  • A verified contact page with no observed form is a paid assessment. A page whose form remains unresolved because of JavaScript or an embed is free.
  • No custom startup fee, per-request fee, AI charge or residential route. Failure notes and default dataset items have zero event price.
  • Every Apify plan pays the same price. Apify adds its standard Actor start charge of $0.00005 a run, shown on the Pricing tab.

What typical jobs cost at the list price:

JobCost
1 completed assessment$0.002
10 completed assessments$0.02
100 completed assessments$0.20
5 completed assessments and 5 failed or uncertain sites$0.01

Both the input limit and the platform limit are checked before fetching a new site. Already delivered assessments count towards the application limit after a restart. Zero-priced notes do not consume an assessment event. To buy 100 assessments, raise maxResults and maxChargeUsd accordingly.

Tips

  • Use an exact contact-page URL when you have one. Homepage discovery is less reliable within a two-page budget.
  • A one-page check only assesses the supplied page. A two- or three-page check can follow contact links from it.
  • Use a new run to refresh previous results. Within a resumed run, a stable result ID prevents a second copy of an already delivered row.
  • Compare sourceUrl and formState across scheduled runs; a no-match or partial result does not prove that no contact form exists.

Use it through the API

Python

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("zaiq/contact-form-finder").call(run_input={"urls": ["https://www.example.org/contact/"], "maxResults": 1, "maxPagesPerSite": 1, "maxChargeUsd": 0.01})
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
print(row)

JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('zaiq/contact-form-finder').call({"urls": ["https://www.example.org/contact/"], "maxResults": 1, "maxPagesPerSite": 1, "maxChargeUsd": 0.01});
const { items } = await client.dataset(run.defaultDatasetId).listItems();

HTTP (one call, results back)

curl -X POST 'https://api.apify.com/v2/acts/zaiq~contact-form-finder/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>' \
-H 'Content-Type: application/json' \
-d '{"urls": ["https://www.example.org/contact/"], "maxResults": 1, "maxPagesPerSite": 1, "maxChargeUsd": 0.01}'

Integrations and schedules

  • Schedules: run it every hour, day or week from the Apify Console (Schedules) and keep a history of results.
  • Make, Zapier, n8n, Google Sheets, Slack, Airtable: connect it through Apify's integrations, or send each finished run to a webhook.
  • Datasets: results stay in the run's dataset; export them or read them by API whenever you need them.

Use it with AI agents (MCP)

Add Apify's MCP server (https://mcp.apify.com) to Claude, ChatGPT, Cursor, VS Code or any MCP client. The agent can find this Actor and run it for you: ask it for "find and assess the public contact pages for these website URLs". AI agents can also pay for runs directly through Apify's agentic payments.

Limits

  • Static HTML only: no browser, JavaScript execution, external stylesheet rendering or iframe fetching. A hidden state controlled only by external CSS may not be detectable.
  • No email, phone, person or social-profile extraction; no form submissions or outreach.
  • Eight seconds, twelve HTTP requests and up to three HTML pages per website. Response bodies are capped at 1 MB decoded and a website at 2 MB decoded. A timeout returns a free note.
  • Only the supplied hostname and its www twin are followed. Different subdomains and country domains must be supplied separately. Cross-domain redirects are reported.
  • HTTP(S) URLs must use standard web ports and have no login credentials or query parameters. Local/private addresses, login routes and unreadable robots rules are refused.
  • The first occurrence of a normalized hostname wins; http/https and www variants are duplicates. Different explicit subdomains are separate inputs.
  • Provider names identify observed embed references; they do not prove the embedded form is an enquiry form. Unknown embeds are free.
  • The release configuration uses direct requests. One datacenter fallback is implemented but disabled pending cloud validation. There is no residential fallback.

FAQ

Does not-observed mean there is no form?

No. It means no qualifying form was seen in the checked HTML. The Actor does not execute scripts. Evidence of a form that needs scripts produces unknown-js instead.

Why was a no-form result charged?

The paid unit is a completed assessment of a confirmed contact page. Unknown JavaScript states, inaccessible pages and unconfirmed page guesses are free.

Why did a site return no-match?

No contact page was confirmed within the supplied scope. Try an exact public contact-page URL in a new run.

Does it fill in or submit forms?

No. It only sends GET requests for public pages and robots rules.

Does it solve bot checks or use an account?

No. Login requirements and bot checks are reported.

What happens if a run restarts?

Rows with result IDs already in the dataset are skipped. Do not interpret this as a guarantee of atomic platform billing; a platform interruption between a row write and its charge requires operator review.

Support

Questions, a site that changed, or a field you need? Open an issue on this Actor's Issues tab: we answer there, usually within a day.


Also found as: contact form finder, website contact page finder, contact form detection, contact page API.