{
  "service": "cf-x",
  "routes": {
    "GET /tweet/:id": "Tweet by numeric id. ?method=auto|graphql|syndication|html (default auto)",
    "GET /tweet?url=…": "Tweet by full x.com URL",
    "GET /tweet/:id/thread?cursor=…&ranking=Relevance|Recency": "TweetDetail conversation: focal + ancestors + replies (auth required). Pass next_cursor back as ?cursor= for more replies.",
    "GET /search?q=…&product=Top|Latest|People|Photos|Videos&count=20&cursor=…": "SearchTimeline (auth required). Pass the response's next_cursor back as ?cursor= for the next page.",
    "GET /user/:handle": "User profile by screen name (auth required).",
    "GET /user/:handle/tweets?count=20&cursor=…": "UserTweets timeline (auth required). Own posts + retweets, no replies.",
    "GET /user/:handle/replies?count=20&cursor=…": "UserTweetsAndReplies timeline (auth required). Includes replies in other people's threads.",
    "GET /user/:handle/likes?count=20&cursor=…": "Likes timeline (auth required). Empty page 1 = likes private or genuinely empty; body includes a `note` field then.",
    "GET /user/:handle/media?count=20&cursor=…": "UserMedia timeline (auth required). Tweets with attached photos/videos only; each tweet carries a `media` array.",
    "GET /user/:handle/followers?count=20&cursor=…": "Followers list (auth required). `count` capped at 50; walk pages via next_cursor.",
    "GET /user/:handle/following?count=20&cursor=…": "Following list (auth required). `count` capped at 50; walk pages via next_cursor.",
    "PUT /auth": "Rotate the KV-backed auth_token (Bearer ADMIN_TOKEN, JSON body { auth_token }). ct0 is derived automatically and self-heals.",
    "GET /health": "Cookie-authed probe (public, never 5xx). Body: { ok, cookie_source, cookie_age_seconds?, upstream_status, latency_ms, error? }",
    "GET /llms.txt": "LLM-oriented usage doc (public, no auth) — point Claude Code or similar agents at this URL"
  }
}