diff --git a/feedback/index.html b/feedback/index.html
index 5ea2725..69a95cb 100644
--- a/feedback/index.html
+++ b/feedback/index.html
@@ -164,8 +164,17 @@
the feedback form. SHAPES (this is the contract to match in the n8n workflow):
GET statusUrl (no query string)
- -> 200 { "seats_left": 7, "seats_total": 10,
+ -> 200 { "seats_left": 7, "seats_total": 10 } <- the intended shape
+ or { "free": 9 } <- what the live route answers today
+ or { "free": 0,
"feedback": [ { "text": "...", "name": "Jane", "publish": "yes" } ] }
+ A count arrives under the documented names first, then the live route's
+ "Free"/"free"; a count must be a whole number >= 0 or it is not on the wire
+ (so "free": "" is skipped and the next key is read). "feedback" (aka "entries")
+ carries the cohort's words: each entry is published only when its "publish" is
+ "yes" (words with the name) or "name" (words without it) — "no", missing or
+ unknown is never rendered. With no seats and no "feedback", the cohort-full
+ state states plainly that nothing is published yet (never a blank list).
POST submitUrl { "form": "claim", "upwork": "" }
-> 200 { "seats_left": 6, "seats_total": 10, "held_until": "2026-11-03T18:40:00Z" }
@@ -184,7 +193,9 @@
// The one route that receives a claim and the feedback form.
submitUrl: "https://n8n.odoo4projects.com/webhook/feedback",
// GET reply keys, in the order they are read. A key not listed here is never read.
- leftKeys: ["seats_left", "seatsLeft"],
+ // "Free"/"free" are the live route's names today; they come last so the documented
+ // shape still wins if it ever arrives. "free": "" is skipped by pick() below.
+ leftKeys: ["seats_left", "seatsLeft", "Free", "free"],
totalKeys: ["seats_total", "seatsTotal"],
feedbackKeys: ["feedback", "entries"],
// One feedback entry. A missing "" means "not on the wire", never a value.