Index: docs/shaer-c2s-api.md
===================================================================
--- docs/shaer-c2s-api.md	(revision a6d703ae0b8f83dc809e8147788960de13ba74e5)
+++ docs/shaer-c2s-api.md	(revision 4c1e327b9d8a84ba2ac7075f7748a6b4a0a171e8)
@@ -96,8 +96,19 @@
 - Send neither and the route behaves exactly as it always did.
 
-The answer arrives as soon as anything the inbox would show has changed, or when
-`wait` runs out — whichever comes first. Either way it is the full, current
-collection with a fresh `shaer:cursor`. An empty-handed return is not an error:
-it means nothing happened, ask again.
+Two possible answers:
+
+| | |
+|---|---|
+| **`200`** | something changed. The full, current collection with a fresh `shaer:cursor`. |
+| **`304`** | nothing changed within `wait`. **No body.** Keep the cursor you have and ask again. |
+
+`304` is not an error — it is the normal answer to a quiet minute, and it is why
+this costs nothing while nothing happens. Sending the whole timeline back every
+`wait` seconds just to say "still nothing" would be a poor trade for saving one
+round trip.
+
+A server that has not run the feed-state migration yet cannot tell change from
+stillness, and answers `200` with the collection every time rather than `304`
+forever. Slower, never wrong.
 
 The cursor moves for **all four** sources this read merges: the timeline,
