Formular zur Lead-Erfassung6 Min. Lesezeit
Formular für Projektanfragen für Agenturen und Freelancer bauen
Ein Formular für neue Projekte für Studios und Freelancer, das Anfragen nach Budget und Zeitpunkt in heiß, warm und unpassend sortiert, bevor jemand das Briefing liest.
Frag nach Leistungen als Checkboxen, nach Budget und Startdatum als feste Auswahl und nach einer Beschreibung, die lang genug ist, um die Eignung zu beurteilen. Schick jede Anfrage per Webhook an ein kleines Relay, das sie nach Budget und Zeitpunkt in die Spuren heiß, warm oder unpassend sortiert. Beantworte dann die heiße Spur am selben Tag und sag der unpassenden Spur innerhalb eines Tages höflich ab, denn beide Antworten bauen deinen Ruf auf.
Was an einer Projektanfrage anders ist
Eine Angebotsanfrage fragt nach einem Preis für einen bekannten Auftrag. Eine Projektanfrage stellt eine größere Frage: Passen wir zusammen? Der Besucher formt das Projekt oft noch, und du entscheidest, ob du ein Erstgespräch dafür investierst. Für ein Studio oder einen Freelancer sind nicht die Leads knapp, sondern die Stunden der Partner, die Briefings lesen, aus denen nie etwas geworden wäre.
Also sammelt dieses Formular genug Struktur, um vor dem Lesen zu sortieren. Drei Antworten reichen: was gebraucht wird, ungefähr wie viel ausgegeben werden kann und wann. Alles, worüber du sprechen willst, steht in einer langen Beschreibung, die nur dann vollständig gelesen wird, wenn die strukturierten Antworten sagen, dass es sich lohnt.
- Die Anfrage kommt als signierter Webhook mit Leistungen, Budget und Startdatum an.
- Das Relay verifiziert die Signatur und bewertet Budget und Zeitpunkt.
- Es prüft die Bewertung.
- Ein Budget ab $30.000 mit Start innerhalb von drei Monaten geht in die heiße Spur.
- Ein niedrigeres Budget oder ein späterer Start geht in die warme Spur.
- Unter $10.000 für alles außer einer Website geht in die unpassende Spur, für eine schnelle, freundliche Absage.
Die Felder
Für ein schlankeres Formular mit einem einzigen Thema starte mit der Kontaktformular-Vorlage. Dieses hier ergänzt die drei Sortierfragen. Hake in der Vorschau mehrere Leistungen an, um zu sehen, wie sie als Liste gespeichert werden.
Vorschau
Führt den Validator von Ikiform in deinem Browser aus. Es wird nichts gesendet.
services ist ein multi_select, gespeichert als Array wie ["brand", "website"]. website ist ein url-Feld, also wird example.com als https://example.com/ gespeichert.| Feld | Warum es so aufgebaut ist |
|---|---|
services | Checkboxen, weil echte Projekte Leistungen kombinieren. Kommt im Webhook als Array an |
budget | Hier Pflicht, anders als in einem Angebotsformular. Deine Spannen sollten dort beginnen, wo dein Mindestauftrag beginnt |
start | Exploring for now ist eine ehrliche Antwort und eine nützliche: Sie geht in die warme Spur |
description | Mindestens 40 Zeichen, höchstens 4.000. Lang genug, um die Eignung zu beurteilen, kurz genug, dass Leute fertig werden |
Das Formular
Checkboxen teilen sich einen name. Der Browser sendet services=brand&services=website, und Ikiform sammelt die Wiederholungen in einer Liste. Den Namen mit [] zu beenden, funktioniert auch, wenn dein Tooling das erwartet.
<form action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="POST">
<label for="name">Name</label>
<input id="name" name="name" autocomplete="name" required />
<label for="email">Email</label>
<input id="email" name="email" type="email" autocomplete="email" required />
<label for="website">Your current website</label>
<input id="website" name="website" inputmode="url" placeholder="example.com" />
<fieldset>
<legend>What do you need?</legend>
<label><input type="checkbox" name="services" value="brand" /> Brand identity</label>
<label><input type="checkbox" name="services" value="website" /> Website</label>
<label><input type="checkbox" name="services" value="app" /> Web or mobile app</label>
<label><input type="checkbox" name="services" value="seo" /> Search and content</label>
</fieldset>
<label for="budget">Budget</label>
<select id="budget" name="budget" required>
<option value="under_10k">Under $10,000</option>
<option value="10k_30k">$10,000 to $30,000</option>
<option value="30k_75k">$30,000 to $75,000</option>
<option value="over_75k">Over $75,000</option>
</select>
<fieldset>
<legend>When should it start?</legend>
<label><input type="radio" name="start" value="this_month" required /> This month</label>
<label><input type="radio" name="start" value="next_quarter" /> In the next three months</label>
<label><input type="radio" name="start" value="exploring" /> Exploring for now</label>
</fieldset>
<label for="description">Tell us about the project</label>
<textarea id="description" name="description" rows="6" minlength="40" maxlength="4000" required></textarea>
<input type="hidden" name="_redirect" value="https://studio.example/inquiry/thanks" />
<input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden />
<button>Send inquiry</button>
</form>Anfragen per Webhook sortieren
Dieser Express-Server empfängt jede Anfrage, verifiziert sie, wählt eine Spur und postet eine kurze Zusammenfassung in den Slack-Channel dieser Spur. Er liest den rohen Body mit express.raw, weil die Signatur genau die Bytes abdeckt, die Ikiform gesendet hat, und übergibt Nodes req.headers unverändert an verifyWebhook.
import express from "express";
import { verifyWebhook, WebhookVerificationError } from "@ikiform/sdk/webhooks";
const BUDGET: Record<string, number> = { under_10k: 0, "10k_30k": 1, "30k_75k": 2, over_75k: 3 };
const START: Record<string, number> = { this_month: 2, next_quarter: 1, exploring: 0 };
const CHANNEL = {
hot: process.env.SLACK_HOT_LEADS!,
warm: process.env.SLACK_LEADS!,
"no-fit": process.env.SLACK_NO_FIT!,
};
function lane(fields: Record<string, unknown>): keyof typeof CHANNEL {
const budget = BUDGET[String(fields.budget)] ?? 0;
const start = START[String(fields.start)] ?? 0;
const services = Array.isArray(fields.services) ? fields.services : [];
if (budget === 0 && !services.includes("website")) return "no-fit";
if (budget >= 2 && start >= 1) return "hot";
return "warm";
}
const app = express();
app.post("/webhooks/inquiries", express.raw({ type: "application/json" }), async (req, res) => {
let event;
try {
event = await verifyWebhook({
payload: req.body.toString("utf8"),
headers: req.headers,
secret: process.env.IKIFORM_WEBHOOK_SECRET!,
});
} catch (error) {
if (error instanceof WebhookVerificationError) return res.status(400).send(error.reason);
throw error;
}
if (event.type !== "submission.created") return res.sendStatus(204);
const fields = event.data.fields;
const which = lane(fields);
const summary = String(fields.description ?? "").slice(0, 280);
const response = await fetch(CHANNEL[which], {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({
text: `[${which}] ${fields.name}: ${(fields.services as string[]).join(", ")}, ${fields.budget}, ${fields.start}\n> ${summary}\nmailto:${fields.email}`,
}),
});
res.sendStatus(response.ok ? 204 : 502);
});
app.listen(3000);- Pass
lane()daran an, wie du verkaufst. Die Schwellenwerte oben sind ein Beispiel, keine Empfehlung. - Die Zusammenfassung sind die ersten 280 Zeichen der Beschreibung. Der vollständige Text steht im Dashboard und in
event.data.fields. - Ein
502, wenn Slack fehlschlägt, lässt Ikiform dieselbe Zustellung etwa 3 Tage lang erneut versuchen, sodass keine Anfrage durch einen Chat-Ausfall verloren geht.
Füge die öffentliche https:-URL des Servers unter Webhooks hinzu. Willst du keinen Server betreiben, funktioniert dieselbe Verzweigung als Router-Schritt in Zapier, Make oder n8n.
Wenn deine eigenen Leistungen wie Spam klingen
Die Spam-Bewertung enthält bekannte Verkaufsphrasen wie seo services, backlinks und rank your website, die jeweils 2 addieren. Verkaufst du Suchmaschinenarbeit, schreibt ein echter Kunde vielleicht genau das. Auch Links summieren sich: website wird als Link gespeichert, und drei oder mehr Links addieren 2.
| Eine echte Anfrage, die enthält | Score | Ergebnis |
|---|---|---|
| „We need SEO services“ und eine Website | +2 | Empfangen |
| Dasselbe plus zwei Links zu Wettbewerbern in der Beschreibung | +2 und +2 | Empfangen, ein Signal von der Grenze entfernt |
| Alles oben Genannte, zweimal innerhalb von 24 Stunden gesendet | +2, +2 und +3 | Spam, über 5 |
Eine Option für Suche und Content in services lässt Kunden sagen, was sie brauchen, ohne die Phrase einzutippen. Prüf den Filter Spam trotzdem wöchentlich; eine verlorene Anfrage über $50.000 kostet mehr als das Lesen von zehn Spam-Posts.
Prüfen, ob es funktioniert
- Sende mit zwei angehakten Leistungen. Die Einsendung speichert
servicesals Liste mit zwei Einträgen. - Sende mit Over $75,000 und This month. Die Zusammenfassung landet im heißen Channel.
- Sende mit Under $10,000 und nur Brand identity. Sie landet im unpassenden Channel.
- Füge eine Beschreibung mit 3.000 Zeichen ein. Die Benachrichtigungs-E-Mail kürzt den Wert bei 500 Zeichen; das Dashboard zeigt alles.
- Stopp deinen Server und sende ab. Die Zustellung zeigt unter Webhooks fehlgeschlagene Versuche und klappt dann, wenn du ihn wieder startest und Retry wählst.
Stolperfallen
- Keine Checkbox angehakt. Eine leere Checkbox-Gruppe sendet nichts, also kann HTML-
requiredsie nicht erzwingen. Ikiform lehnt den Post mitChoose at least one optionab; zeig diesen Fehler mit derfetch-Version aus der Anleitung zur Lead-Erfassung auf der Seite an. - Optionen umbenennen. Labels kannst du frei ändern. Werte nur zusammen mit dem Relay, sonst landen Anfragen in der falschen Spur.
- Lange Briefings in der E-Mail. Benachrichtigungs-E-Mails zeigen bis zu 20 Felder und 500 Zeichen pro Wert. Die Beschreibung wird dort gekürzt. Workspace-Mitglieder bekommen in der E-Mail einen Link zur vollständigen Einsendung.
- Die Absage. Ikiform sendet der Person, die das Formular ausgefüllt hat, nichts, also hört ein unpassender Lead nichts, außer jemand antwortet. Eine zweizeilige Absage mit einer Empfehlung hält die Tür offen.
Fragen
Kontaktdaten, die benötigten Leistungen, eine Budgetspanne, ein Startdatum und eine Beschreibung des Projekts. Mit den drei Fragen mit fester Auswahl sortierst du Anfragen, bevor jemand die Beschreibung liest.
Checkboxen mit gleichem Namen werden in einer Liste gesammelt. Mit einem definierten multi_select-Feld akzeptiert Ikiform nur gelistete Werte und speichert sie als Array, und genau das trägt der Webhook.
Bei einer Projektanfrage meist ja: Es ist das beste einzelne Signal für die Eignung, und Spannen, die bei deinem Mindestauftrag beginnen, lassen die Frage normal wirken. Bei einer Angebotsanfrage, bei der du den Preis festlegst, mach es optional.
Phrasen wie seo services zählen als Spam-Signal, und Links erhöhen den Score. Zusammen mit einer identischen Wiederholung innerhalb von 24 Stunden erreicht das den Schwellenwert von 5. Markiere sie als kein Spam, um E-Mail und Webhook zu senden, und biete Suchmaschinenarbeit als Checkbox an, damit Kunden die Phrase nicht eintippen müssen.
Hängst du bei einem Schritt fest oder willst eine Anleitung für deinen Fall? Schreib an hello@ikiform.com.