# 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.

Veröffentlicht am 2026-10-25 · https://ikiform.com/de/guides/lead-capture/project-inquiry

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.

Diagramm: Wie ein Relay Projektanfragen in Spuren sortiert

1. Die Anfrage kommt als signierter Webhook mit Leistungen, Budget und Startdatum an.
2. Das Relay verifiziert die Signatur und bewertet Budget und Zeitpunkt.
3. Es prüft die Bewertung.
4. Ein Budget ab $30.000 mit Start innerhalb von drei Monaten geht in die heiße Spur.
5. Ein niedrigeres Budget oder ein späterer Start geht in die warme Spur.
6. Unter $10.000 für alles außer einer Website geht in die unpassende Spur, für eine schnelle, freundliche Absage.

Die Spuren sind Chat-Channels. Niemand wird automatisch abgelehnt: Jede Spur beantwortet weiterhin ein Mensch, nur in anderer Reihenfolge.

## Die Felder

Für ein schlankeres Formular mit einem einzigen Thema starte mit der [Kontaktformular-Vorlage](https://ikiform.com/forms/contact-form). Dieses hier ergänzt die drei Sortierfragen. Hake in der Vorschau mehrere Leistungen an, um zu sehen, wie sie als Liste gespeichert werden.

Formular: Project inquiry

- **Name** (`name`, text, Pflichtfeld)
- **E-Mail** (`email`, email, Pflichtfeld)
- **Deine aktuelle Website** (`website`, url)
- **Was brauchst du?** (`services`, multi_select, Pflichtfeld)
- **Budget** (`budget`, select, Pflichtfeld)
- **Wann soll es losgehen?** (`start`, radio, Pflichtfeld)
- **Erzähl uns vom Projekt** (`description`, textarea, Pflichtfeld)

`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.

`start-a-project.html`:

```html
<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`.

`server.ts`:

```ts
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](https://ikiform.com/blog/form-submissions-to-zapier.md), [Make](https://ikiform.com/blog/form-submissions-to-make.md) oder [n8n](https://ikiform.com/blog/form-submissions-to-n8n.md).

## 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

1. Sende mit zwei angehakten Leistungen. Die Einsendung speichert `services` als Liste mit zwei Einträgen.
2. Sende mit **Over $75,000** und **This month**. Die Zusammenfassung landet im heißen Channel.
3. Sende mit **Under $10,000** und nur **Brand identity**. Sie landet im unpassenden Channel.
4. Füge eine Beschreibung mit 3.000 Zeichen ein. Die Benachrichtigungs-E-Mail kürzt den Wert bei 500 Zeichen; das Dashboard zeigt alles.
5. 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-`required` sie nicht erzwingen. Ikiform lehnt den Post mit `Choose at least one option` ab; zeig diesen Fehler mit der `fetch`-Version aus der [Anleitung zur Lead-Erfassung](https://ikiform.com/de/guides/lead-capture.md#form) 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

### Was sollte ein Formular für Projektanfragen 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.

### Wie werden Checkbox-Antworten gespeichert?

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.

### Sollte ich in einem Anfrageformular ein Budget verlangen?

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.

### Warum ist eine echte Anfrage zu SEO im Spam gelandet?

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.

## Weitere Anleitungen

- [Formular zur Lead-Erfassung](https://ikiform.com/de/guides/lead-capture.md): Ein Lead-Formular auf deiner eigenen Site, das dich per E-Mail mit Reply-To benachrichtigt, den Team-Chat anpingt und dein CRM füttert, damit du antwortest, solange der Lead noch da ist.
- [Formular für Angebotsanfragen](https://ikiform.com/de/guides/lead-capture/quote-request.md): Ein Formular für Angebotsanfragen, das Briefings als geteilte Links statt als Uploads sammelt, jeder Anfrage ein Fälligkeitsdatum gibt und linklastige Leads aus dem Spam hält.
- [Leads an HubSpot oder Pipedrive](https://ikiform.com/de/guides/lead-capture/leads-to-crm.md): Bilde jeden signierten Ikiform-Webhook auf HubSpots Kontakt-Upsert oder die Personen- und Lead-Aufrufe von Pipedrive ab, ohne doppelte Kontakte bei einer wiederholten Zustellung.
- [Formular für Beratungsanfragen](https://ikiform.com/de/guides/lead-capture/consultation-request.md): Ein Formular für Beratungsanfragen für Steuerberater, Anwälte, Coaches und Praxen, das fragt, wie und wann angerufen werden soll, und heikle Details für das Gespräch lässt.
- [Formular für Demo-Anfragen](https://ikiform.com/de/guides/lead-capture/demo-request.md): Ein Formular zum Demo-Buchen, das den Lead speichert und den Besucher dann mit vorausgefülltem Namen und E-Mail zu Cal.com oder Calendly schickt.
- [Lead-Formular mit Next.js](https://ikiform.com/de/guides/lead-capture/nextjs.md): Ein Lead-Formular für den Next.js App Router, das in einer Server Action mit Zod validiert, UTMs des ersten Kontakts in einem Cookie hält und qualifizierte Leads in deinen Kalender schickt.
