# Anmeldeformular für Helfer mit Schichten, für Events und Festivals

> Ein Anmeldeformular für Helfer, in dem man Schichten wählt, mit Telefonnummer für den Tag, und ein Skript, das unterbesetzte Schichten zeigt und den Dienstplan erstellt.

Veröffentlicht am 2026-10-25 · https://ikiform.com/de/guides/event-registration/volunteer-signup

Lass Helfer in einem Formular jede Schicht ankreuzen, die sie übernehmen können, mit Telefonnummer, T-Shirt-Größe und Notfallkontakt, und sende es an Ikiform. Ikiform speichert jede Anmeldung und informiert die Koordinatoren per E-Mail, besetzt oder schließt aber keine Schichten. Führe also ein kurzes Skript aus, das die Helfer pro Schicht mit dem Bedarf vergleicht und einen Dienstplan schreibt. Fülle unterbesetzte Schichten, indem du die übrigen Helfer direkt fragst.

## Was bei Helfern anders ist

Ein RSVP stellt eine Frage: Kommst du? Eine Helferanmeldung fragt nach dem Wann, und die Antwort zählt nur im Verhältnis zu dem, was jede Schicht braucht. Der Aufbau um 7 Uhr braucht sechs Leute und bekommt zwei; der sonnige Nachmittag braucht zehn und bekommt neunzehn. Es geht nicht ums Zählen, sondern um die Abdeckung.

- **Verfügbarkeit statt einer einzigen Wahl.** Leute können mehrere Schichten übernehmen. Frag nach jeder Schicht, die sie machen könnten, und teile von dort aus ein, statt sie raten zu lassen, was gebraucht wird.
- **Erreichbarkeit am Tag selbst.** E-Mail ist für die Planung. Am Tag selbst brauchst du eine Handynummer und einen Notfallkontakt für jeden Helfer.
- **Dinge zum Bestellen.** T-Shirts, Lanyards und Mittagessen, nach Größe und Anzahl.
- **Alter.** Viele Events verlangen für jeden Helfer Volljährigkeit oder die Zustimmung eines Erziehungsberechtigten. Frag deine Organisation, was gilt; eine Checkbox hält die Antwort fest, ist aber keine rechtliche Prüfung.

Helferplattformen wie SignUpGenius bieten Anmeldungen mit Slots, die einen Slot schließen, wenn er voll ist. Wenn du harte Limits pro Slot brauchst, nutze so eine Plattform. Ikiform passt zu Organisatoren, die das Formular auf ihrer eigenen Site haben wollen und Schichten gern von Hand aus einer sauberen Liste zuteilen.

Diagramm: Aus der Verfügbarkeit der Helfer einen Dienstplan machen, der die Lücken zeigt

1. Helfer kreuzen im Anmeldeformular jede Schicht an, die sie übernehmen könnten, und es wird an Ikiform gesendet.
2. Ikiform speichert jede Anmeldung und informiert die Koordinatoren per E-Mail.
3. Ein Skript liest die Anmeldungen über die API und vergleicht die Helfer pro Schicht mit dem Bedarf jeder Schicht.
4. Es schreibt rota.csv mit Namen und Telefonnummern für jede Schicht.
5. Unterbesetzte Schichten fallen sofort auf, etwa der Aufbau mit 2 von 6, sodass du Helfer fragen kannst, die anderswo übrig sind.

Ikiform hält die Verfügbarkeit fest. Das Skript macht daraus die Abdeckung, und eine Koordinatorin trifft die letzten Entscheidungen.

## Das Formular

Gruppiere die Schichten nach Tag, damit man sie überfliegen kann. Die Checkboxen heißen `shifts[]`, daher wird selbst ein einzelnes Häkchen als Liste gespeichert. Es funktioniert als einfaches HTML auf jeder Site und in jedem Baukasten, der Embeds erlaubt:

`volunteer.html`:

```html
<form action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="post">
  <label>Name <input name="name" autocomplete="name" required></label>
  <label>Email <input name="email" type="email" autocomplete="email" required></label>
  <label>Mobile number for the day <input name="phone" type="tel" autocomplete="tel" placeholder="+44 7700 900123" required></label>

  <fieldset>
    <legend>Shifts you can do</legend>
    <p>Saturday</p>
    <label><input type="checkbox" name="shifts[]" value="sat_setup"> 7:00 to 10:00, setup</label>
    <label><input type="checkbox" name="shifts[]" value="sat_day"> 10:00 to 14:00</label>
    <label><input type="checkbox" name="shifts[]" value="sat_late"> 14:00 to 18:00</label>
    <p>Sunday</p>
    <label><input type="checkbox" name="shifts[]" value="sun_day"> 10:00 to 14:00</label>
    <label><input type="checkbox" name="shifts[]" value="sun_pack"> 14:00 to 17:00, pack-down</label>
  </fieldset>

  <label>Where you'd like to help
    <select name="role">
      <option value="anywhere">Anywhere</option>
      <option value="welcome">Welcome desk</option>
      <option value="food">Food stall</option>
      <option value="stewarding">Stewarding</option>
    </select>
  </label>
  <label>T-shirt size
    <select name="tshirt" required>
      <option value="s">S</option><option value="m" selected>M</option><option value="l">L</option>
      <option value="xl">XL</option><option value="xxl">XXL</option>
    </select>
  </label>
  <label>Emergency contact name and number <input name="emergency_contact" required maxlength="160"></label>
  <label><input type="checkbox" name="adult" required> I'm 18 or over, or a parent or guardian is filling this in with me</label>

  <input type="hidden" name="_redirect" value="https://fair.example/volunteers/thanks">
  <input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden>
  <button type="submit">Sign me up</button>
</form>
```

Füge diese Definition im Tab **Fields** des Formulars ein. Der Server lehnt dann eine Anmeldung ohne Schichten, mit einer Telefonnummer, die keine ist, oder mit nicht angehakter Altersbox ab, egal von welcher Seite sie kommt:

Formular: Volunteer signup

- **Name** (`name`, text, Pflichtfeld)
- **E-Mail** (`email`, email, Pflichtfeld)
- **Handynummer für den Tag** (`phone`, phone, Pflichtfeld)
- **Schichten, die du übernehmen kannst** (`shifts`, multi_select, Pflichtfeld)
- **Wo du gern helfen würdest** (`role`, select)
- **T-Shirt-Größe** (`tshirt`, select, Pflichtfeld)
- **Name und Nummer des Notfallkontakts** (`emergency_contact`, text, Pflichtfeld)
- **Ich bin 18 oder älter, oder ein Elternteil bzw. Erziehungsberechtigter füllt das mit mir aus** (`adult`, checkbox, Pflichtfeld)

`shifts` ist ein `multi_select` mit `min_items: 1`. `phone` ist ein `phone`-Feld, das das Format der Nummer prüft. `adult` muss angehakt sein.

| Feld | Warum es da ist |
| --- | --- |
| `phone` | Schichtänderungen per SMS schicken und Leute am Tag selbst erreichen |
| `shifts` | Verfügbarkeit, aus der du einteilst |
| `role` | Vorlieben, damit der Empfang die Leute bekommt, die darum gebeten haben |
| `tshirt` | Die Bestellung, die du zwei Wochen vorher aufgibst |
| `emergency_contact` | Für das Erste-Hilfe-Team, nicht fürs Marketing |
| `adult` | Die Altersregel deiner Organisation, festgehalten in einer Einsendung, die ihr eigenes `created_at` behält |

> Telefonnummern und Notfallkontakte sind personenbezogene Daten über Menschen, die sich nicht selbst anmelden. Bewahre den Export an einem privaten Ort auf, teile den Dienstplan nur mit den Schichtleitungen und lösche die Einsendungen nach dem Event.

## Den Dienstplan erstellen und die Lücken sehen

Führe das mit Node und einem geheimen API-Schlüssel aus, wann immer du den Überblick willst. Es nimmt die neueste Anmeldung jedes Helfers, gibt jede Schicht als besetzt, unterbesetzt oder mit Überschuss aus und schreibt `rota.csv` mit Namen und Nummern für jede Schicht:

`rota.ts`:

```ts
import { writeFileSync } from "node:fs";
import { createClient } from "@ikiform/sdk";

const NEEDED: Record<string, number> = { sat_setup: 6, sat_day: 10, sat_late: 10, sun_day: 8, sun_pack: 6 };
const ikiform = createClient({ apiKey: process.env.IKIFORM_SECRET_KEY! });
const people = new Map<string, Record<string, unknown>>();

for await (const submission of ikiform.submissions.iterate({ formId: "frm_xxxxxxxxxxxxxxxx", status: "received", limit: 100 })) {
  const email = String(submission.fields.email ?? "").trim().toLowerCase();
  if (email && !people.has(email)) people.set(email, submission.fields);
}

const cell = (value: unknown) => `"${String(value ?? "").replaceAll('"', '""')}"`;
const rows = [["shift", "name", "phone", "role", "tshirt"].join(",")];

for (const [shift, needed] of Object.entries(NEEDED)) {
  const team = [...people.values()].filter((fields) => (fields.shifts as string[] | undefined)?.includes(shift));
  const state = team.length < needed ? `SHORT ${needed - team.length}` : team.length > needed ? "spare" : "ok";
  console.log(`${shift.padEnd(10)} ${team.length}/${needed} ${state}`);
  for (const fields of team) {
    rows.push([shift, fields.name, fields.phone, fields.role, fields.tshirt].map(cell).join(","));
  }
}

writeFileSync("rota.csv", `${rows.join("\n")}\n`);
```

- Listen kommen neueste zuerst, daher wird ein Helfer, der sich mit geänderter Verfügbarkeit erneut anmeldet, mit seiner neuesten Antwort gezählt.
- Eine Person erscheint unter jeder Schicht, die sie angekreuzt hat. Das ist Verfügbarkeit. Reduziere sie in der CSV auf Zuteilungen und sag jeder Person ihre endgültigen Schichten.
- Kommas und Anführungszeichen in Namen werden escaped, sodass die CSV in jeder Tabellenkalkulation sauber aufgeht.

Für einen schnellen Blick ohne Code exportiere die CSV unter **Submissions** und filtere die Spalte `shifts` nach dem Wert einer Schicht, etwa `sat_setup`. Mehrfachauswahl-Werte stehen im Export zusammen in einer Zelle.

## Von der Verfügbarkeit zur Zuteilung

1. Führe zwei Wochen vorher den Dienstplan aus und bestelle T-Shirts anhand der Zahlen in `tshirt`.
2. Schreib für jede unterbesetzte Schicht den Helfern, die übrig sind und diese Schicht auch angekreuzt haben. Sie haben schon gesagt, dass sie können.
3. Schick jedem Helfer seine endgültigen Schichten aus deinem E-Mail- oder Messaging-Tool. **Reply** in der Benachrichtigungs-E-Mail geht direkt an ihn.
4. Druck am Vortag den Dienstplan mit Telefonnummern für die Schichtleitungen aus.

Ikiform schickt der Person, die das Formular ausfüllt, keine E-Mail. Benachrichtigungs-E-Mails gehen nur an dich und dein Team, es gibt also keinen Autoresponder, keine Bestätigungs-E-Mail und kein Double-Opt-in. Verschicke sie aus deinem E-Mail-Tool, ausgelöst durch einen [Webhook](https://ikiform.com/de/docs/webhooks.md). Helfer vergessen, wofür sie sich eingetragen haben, also schick den endgültigen Dienstplan eine Woche vorher persönlich und noch einmal am Vorabend.

Um von jeder Anmeldung dort zu erfahren, wo dein Team ohnehin kommuniziert, schick den Webhook an [Slack](https://ikiform.com/blog/form-submissions-to-slack.md) oder [Discord](https://ikiform.com/blog/form-submissions-to-discord.md). Die Koordinatoren sehen dann, wie sich eine unterbesetzte Schicht füllt.

## Vor der Helfersuche prüfen

1. Füge unter **Allowed domains** des Formulars die Domain deiner Site hinzu, plus `localhost`, während du entwickelst. Lass das Feld leer, um Posts von überall anzunehmen.
2. Melde dich mit einer angekreuzten Schicht an. Im Dashboard ist `shifts` eine Liste mit einem Wert.
3. Versuch, dich ohne Schichten oder mit nicht angehakter Altersbox anzumelden. Der Browser hält dich auf, und ein manipulierter Post bekommt `422`.
4. Prüfe das Postfach jedes Benachrichtigungsempfängers. Jeder bekommt eine E-Mail mit den Feldern, und **Reply** geht an den Absender, wenn das Formular ein `email`-Feld hat.
5. Führe das Dienstplan-Skript aus. Dein Test erscheint unter seiner Schicht, und jede andere Schicht wird als unterbesetzt angezeigt.
6. Öffne `rota.csv` in einer Tabellenkalkulation und prüfe die Spalte mit den Telefonnummern.

## Stolperfallen

| Problem | Was zu tun ist |
| --- | --- |
| Eine einzelne Schicht wird als Text gespeichert, nicht als Liste | Die Checkboxen heißen `shifts` ohne `[]`, und es ist kein Feld definiert. Benenne sie in `shifts[]` um oder definiere `shifts` als `multi_select`. |
| `422` bei `phone` | Die Nummer sieht nicht wie eine Telefonnummer aus. Bitte im Hilfetext um die Ländervorwahl, wie es die Definition tut. |
| Ein Helfer erscheint zweimal im Dienstplan | Er hat sich mit zwei verschiedenen E-Mail-Adressen angemeldet. Führe die Einträge von Hand zusammen; das Skript ordnet nach E-Mail-Adresse zu. |
| `422 validation_failed` | Der Post passt nicht zur Felddefinition des Formulars. `error.fields` nennt jedes Feld und den Grund. Gleiche den `name` des Eingabefelds an die Feld-ID an. |
| `429 rate_limited` | Ein Besucher hat mehr gesendet, als das Rate-Limit des Formulars erlaubt. Standard erlaubt 5 pro Minute und Besucher. Warte `Retry-After` ab oder wähle Relaxed oder Custom für Formulare, die von einer gemeinsamen IP aus senden. |

## Fragen

### Kann Ikiform eine Schicht schließen, wenn sie voll ist?

Nein. Ikiform hat keine Limits pro Option. Frag nach Verfügbarkeit, zähle die Helfer pro Schicht mit einem Skript oder einer Tabelle und teile die Leute selbst ein. Nutze ein Anmeldetool mit Slots, wenn harte Limits wichtiger sind.

### Wie sammle ich mehrere Schichten von einem Helfer?

Verwende Checkboxen mit dem Namen shifts[] und definiere shifts als multi_select-Feld. Jede angekreuzte Schicht wird in einer Liste gespeichert, und min_items: 1 macht mindestens eine zur Pflicht.

### Können Helfer ihre Schichten ändern?

Bitte sie, sich mit derselben E-Mail-Adresse erneut anzumelden. Das Dienstplan-Skript nutzt die neueste Anmeldung jedes Helfers, sodass die neue Verfügbarkeit die alte ersetzt.

### Kann Ikiform der Person, die das Formular gesendet hat, eine E-Mail schicken?

Nein. Ikiform schickt E-Mails an dich und dein Team, nicht an den Absender, es gibt also keinen Autoresponder und keine Bestätigungs-E-Mail. Sende einen Webhook an dein E-Mail-Tool und verschicke die Bestätigung von dort.

### Ist Ikiform kostenlos?

Nein, es gibt keinen kostenlosen Tarif. Testen ist kostenlos: Du kannst 50 Testeinsendungen pro Monat von localhost senden, bevor du zahlst. Für den Livebetrieb startet Pro bei $6/Monat für 500 Einsendungen, oder du zahlst einmalig 10.000 Einsendungen für $49 oder 50.000 Einsendungen für $149, mit Guthaben, das nie verfällt.

## Weitere Anleitungen

- [Eventanmeldung](https://ikiform.com/de/guides/event-registration.md): Nimm Zusagen auf deiner eigenen Eventseite entgegen: Formular, Begleitpersonen-Limit, ehrliche Teilnehmerzahl, Schließen bei voller Kapazität und Check-in-Liste, ohne Ticketing-App.
- [Ohne Eventbrite](https://ikiform.com/de/guides/event-registration/without-eventbrite.md): Nimm Anmeldungen für ein kostenloses Community-Event auf deiner eigenen Site entgegen: Sessionwahl, Bestätigungsmail aus deinem eigenen Tool, Raumzahlen und Check-in-Liste.
- [Hochzeits-RSVP](https://ikiform.com/de/guides/event-registration/wedding-rsvp.md): Ein RSVP-Formular für eine selbst gebaute Hochzeitswebsite: eine Antwort pro Einladung, ein Menü pro Gast, eine Frist und eine Liste, wer noch nicht geantwortet hat.
