shorts worker: Street Soccer Pro shorts (posted clips): counts, likes, follows, verdicts, TOP CLIPS, WEEKLY BEST Every /v1 route but /v1/erasure takes Authorization: Bearer INGEST_TOKEN and a universe id (game.GameId); each universe keeps its own shorts, and only those in UNIVERSES are served (403 otherwise). Bodies are shorts.v1 protobuf (proto/shorts.proto), Content-Type application/x-protobuf, POST only. Tapes live in the game's DataStore, not here. POST /v1/post PostRequest -> PostResponse. Stores a short (LIVE). Result 3 and nothing stored when sharing is false or the owner already has a HIDDEN or held short of the same moment. Over 30 live shorts per creator the oldest ones not crowned and not on an open shortlist are retired, listed in retired and queued in forget. Same ref twice: result 1. Never writes the creator's sharing flag. Keeps up to 8 tags (ids 1..64, others ignored); every Short answered carries its tags. Indexes the kind and tag names, owner name and display name and the short's text (first 400 bytes) for search. POST /v1/item ItemRequest -> Result. Stores the RecommendationService ItemId of the owner's short. POST /v1/vis VisRequest -> Result. Owner sets PUBLIC 1, UNLISTED 2, PRIVATE 3 (LIVE shorts only). POST /v1/delete DeleteRequest -> Result. Owner deletes; likes and reports go with it; queued in forget. POST /v1/page PageRequest -> PageResponse. Metadata, counts, liked, following and mark for the refs this viewer may see (LIVE, PUBLIC, creator sharing; owners see their own), in the order asked. POST /v1/events EventsRequest -> EventsResponse. Rows are keyed so a replay changes nothing; counts are summed once per batch id (result 1 = batch seen within the last flush or two). Verdicts only while the short is PUBLIC and LIVE, one per viewer per short for 2-3 weeks; likes (with reaction), follows (500 per user), reports, votes (open week's nominees, vote phase only) apply at once; counters reach the shorts every 30 min. Three reporters with w = 1 hide a short (listed in hidden). forgotten acks removed shorts; forget leases up to 50 still to remove from RecommendationService and DataStore for 5 min (unacked ones come back). POST /v1/chart ChartRequest -> ChartResponse. tab 2 FOLLOWING, 3 TOP (chart 1 TRENDING, 2 WEEK, 3 ALL_TIME), 4 WEEKLY (week 0 = latest; no nominees during review; winner = latest crowned), 5 CREATOR, 6 LINK (ref; UNLISTED too), 7 MINE, 8 SEARCH (query text, else tag; chart 1 TRENDING, 3 ALL_TIME or 4 NEW over the newest 500 matches plus that chart's matching members; TOP's visibility, one per moment). Tab 1 is a 400. POST /v1/suggest SuggestRequest -> SuggestResponse. Live search box: up to 6 creators by username or display name prefix (most followed first) and 6 PUBLIC, LIVE shorts by full-text match (bm25 blended with the trend score; owner_name filled). Text is normalized as @shared/shorts.query: trimmed, one leading @ dropped, whitespace collapsed, ASCII lowercased; outside 2..32 characters = no hits. POST /v1/creator CreatorRequest -> CreatorResponse. Last-known IsContentSharingAllowed; a flip lists PUBLIC items to make Private (hide) or Public again (show). POST /v1/moderate ModerateRequest -> ModerateResponse. action 1 HOLD, 2 CLEAR, 3 HIDE, 4 RESTORE, 5 REMOVE, 6 VETO (this week's shortlist, review and vote phases), 7 BAN (every short of user). Removals queue forget. POST /v1/erasure Roblox right-to-erasure webhook, JSON, signed with ERASURE_SECRET (roblox-signature header). Queues the user; the hourly job erases 20 users a run and queues their shorts in forget. Bookmarks: page, chart and suggest read through a D1 session (read replicas) started from the request's bookmark (empty = any replica); every other route writes through a session started on the primary. Every response carries the session's bookmark; send the latest one back on reads to see your own writes. result: 0 ok, 1 already, 2 missing, 3 forbidden, 4 cap (reserved), 5 closed. Crons (UTC): :30 flush + TRENDING; :00 flush + holds + weekly steps (shortlist Monday 00:00, vote Monday 12:00, crown Wednesday 00:00, each caught up if missed) + every chart + erasures; 04:23 drops old verdict weeks, old reports. 400 malformed, 401 auth, 5xx failure, as plain text. X-Body-Encoding: base64 carries protobuf bodies as base64 text.