Once the RSVPs are counted the real chain begins: a row per guest, seating, meal choices, dietary constraints, and a headcount that reaches the invoice.
Key takeaways
- An invitation is not a guest. One invitation can bring four people, and everything after the count - seating, meals, billing - needs a row per person.
- A meal count made of choices and defaults is not one number. A `meal_source` field separates them, and without it nobody knows how many meals were actually chosen.
- A dietary constraint is a coded list, not a note. "No nuts" in a text field never reaches the kitchen in a form anyone can filter on.
- Seating is a constraint problem with two kinds of rule: a hard constraint that invalidates an assignment and a soft preference that lowers its score. Mixing them produces a plan that looks fine and cannot be executed.
- The guaranteed number, the number actually served and the number billed are three different figures. The rule linking them is a commercial term; the system's job is to keep all three, not to decide between them.
Counting the replies is the beginning, not the end. Once a number exists, a four-layer chain starts, and each layer can contradict the one before it: a row per guest, a seat at a table, a meal choice, and a final number that reaches the invoice. Events fail between those layers, not in the count.
Where the RSVP ends and the operational chain begins
Counting replies is its own problem and is handled separately in RSVP by SMS and WhatsApp. This article starts immediately after: an agreed number of attendees exists, and it now has to become tables, meals and an invoice.
The boundary between the two is sharp and worth stating:
- Before the boundary: who replied, what they said, when, on which channel, and how two contradictory replies are adjudicated.
- On the boundary: the declared headcount per invitation. It is the single field that crosses from the reply layer into the operational layer.
- After the boundary: who those people are, where they sit, what they eat, and what they cost.
The common failure is the second layer trying to work directly off invitations. A family invitation with four heads cannot be seated, because it has no four rows in any table. Somebody will split it by hand in a spreadsheet, and that is the exact moment two versions of the list begin to exist.
The guest record: one row per person
| Field | Example | Note |
|---|---|---|
guest_id | G-00417 | Created when the invitation is split, never typed |
invitation_id | INV-0132 | Points back to the invitation and the reply |
display_name | Dana L. | Often empty for a partner whose name was not given |
is_named | false | Distinguishes an identified guest from a counted place |
age_band | child | Adult, child, infant. Affects both the meal and the seat |
table_id | T-14 | Assigned by the solver, not typed |
seat_no | 7 | Only needed when seating is numbered |
meal_choice | fish | From a closed list |
meal_source | guest_reply | Guest reply, household default, venue default, or manual |
dietary_codes | ["gluten_free"] | A coded array |
allergen_codes | ["nuts"] | A separate array, never mixed with preference |
accessibility | wheelchair | A hard seating constraint |
checked_in_at | 2026-05-19T19:42+03:00 | Recorded at the door, comparable against the forecast |
is_named looks redundant until you look at a real list: a guest who declared "me plus one" generates a second row with no name. That row has to exist, or it has no seat and no meal, but it must not appear on a door list as though it were a known person.
Why is a count of 402 meals not 402 chosen meals?
Because somebody else decided some of them. At an event with 402 confirmed guests, the split looks like this:
| Meal source | Count | What it means |
|---|---|---|
guest_reply | 288 | The guest chose for themselves |
household_default | 73 | The invitation holder chose for the whole family |
venue_default | 32 | No choice arrived, the venue default was applied |
manual | 9 | Changed by the planner after a phone call |
The number 402 is correct either way, but 32 of those meals represent a guest who was never asked or never answered, and the chance they want something else on the night is far higher. A planner who sees only the total orders 402 and is surprised. A planner who sees the split knows to hold contingency against 32, not against 402.
The field also settles arguments: when a guest insists they asked for a vegetarian meal, you can see at once whether the choice came from them or from the person who held their invitation.
Seating: hard constraints against soft preferences
Table assignment fails when every request is treated as the same kind of thing. There are only two kinds, and the classification is decided in advance:
- Hard constraints: table capacity, wheelchair access, proximity to a door or facilities for a medical reason, and people who must not be seated together. An assignment that breaches a hard constraint is rejected, not scored lower.
- Soft preferences: sitting with friends, closeness to the stage, distance from the speakers, keeping one side of the family together. These are scored, and each plan gets a total.
- Real capacity. A table of 12 does not take 12 guests if one of them uses a wheelchair. Effective capacity is derived from the constraints, not from the venue's spec sheet.
- Held places. Immediate family, suppliers, the photographer. They occupy physical space and sometimes appear on no guest list at all.
- Changes on the day. Three cancellations on one table do not require re-solving the room. The plan is versioned, and every change is a delta against the version that was printed.
The rule that removes most of the pain: the number of assigned seats must equal the number of confirmed guests, and any gap is shown as a list of names rather than a number. A gap of six seats is six people somebody will be finding a chair for at eight in the evening.
Dietary and allergen data need a coded list
A free-text note never reaches the kitchen. What reaches the kitchen is a count per code, which is why these are two separate fields:
- Dietary preference - vegetarian, vegan, no meat, a specific kosher requirement. This is a choice and it shapes a menu.
- Allergen - not a preference, and it requires separation in the kitchen. Food authorities publish a closed list of allergens that must be declared, and the UK Food Standards Agency guidance for food businesses is one written, available version of such a list. A closed vocabulary beats a free-text field because it can be counted, translated and filtered on.
Three practical rules follow:
- An allergen is stored separately from a preference. A guest can be vegan and allergic to sesame, and those are two entirely different facts.
- Every allergen change carries a timestamp and a source. A change arriving two days out must reach the supplier as an explicit message, not as a file resent.
- The supplier list goes out as a count per code rather than as a list of names, except where service is individually plated. Less personal data leaves the system, and the kitchen still gets exactly what it needs.
How does the final headcount reach the invoice?
Not as one number but as four, each with a different origin:
| Number | Example | Origin |
|---|---|---|
| Confirmed at list lock | 402 | The reply layer, at the lock date |
| Guaranteed to the supplier | 410 | The planner's decision, contingency included |
| Actually served | 396 | Door count on the night |
| Billed | Per the agreement | The rule agreed between the parties |
The rule connecting the second row to the fourth is a commercial term in the supplier agreement, not a universal one. What the system must do is keep the first three numbers with the date and time each was set, so the invoice can be checked. A planner who kept only the number given over the phone arrives at that conversation with no evidence.
Additions that surface after the event, such as extra staff hours or items consumed beyond the menu, enter as separate billable lines with an approval. Tracking the open balance from there is covered in collecting from customers with treatment paths, and the wider administrative picture in automation for event planners.
What breaks on the day
- A spreadsheet alongside the system. Both were updated and neither is right.
- A child counted as an adult. It changes both the meal and the effective capacity of the table.
- A meal changed by phone and never recorded. The kitchen cooks from the file you sent yesterday.
- A table deleted after printing. Table numbers on the signage no longer match the door list.
- A guest with no name and no meal. Counted in the total, present in no operational list.
- A door count that was never saved. Without
checked_in_atthere is no way to show how many people actually arrived.
Sources
Frequently asked questions
When should the list be locked?
On the date set in the supplier agreement, and at a fixed hour rather than a whole day. Locking creates a stored version of the list, and every subsequent change is recorded as a delta against it. That is what lets you show exactly what changed after the lock, which is precisely the dispute that surfaces on the invoice.
What do you do about a guest who arrives without confirming?
Add a guest row in real time with `meal_source` set to manual, and assign them to a free seat or one that has opened up. The record matters even when nothing can be done about the meal, because it explains the gap between the number served and the number confirmed at the end of the night.
Should guest names be kept after the event?
Not for long. What settlement and record-keeping need are the counts and the dates, not the list of names. A deletion policy decided in advance - for example removing guest details a month after the event while retaining the aggregate figures - reduces the personal data held without weakening the ability to check an invoice.
How do you notify a supplier of a last-minute change?
With a dedicated message containing only the delta, never by resending the full file. Two gluten-free changes sent inside a 400-row file will be missed. The message is logged with a time and an acknowledgement, so what was communicated and when is not in doubt.
Keep reading
Related service
Business Automation
I build custom automations that remove repetitive work end to end.
About the author
Yehonatan Saadia
Freelance automation, web & MVP developer
I'm Yehonatan Saadia, a senior developer who builds business automation, custom websites, and MVPs for small and mid-sized companies across the US, Europe, and Israel. These guides come from real client work, not theory.
Work with meHave a project like this?
Tell me what you're trying to automate or build. I reply within 24 business hours with a few targeted questions, then we walk through it on a free 30-minute call, with no commitment. You come away with a scope, a timeline and a fixed price - or a straight answer that it isn't worth building.
