Guides · Follows

Docs › Follows

Follows

Follow or unfollow other names to build a social graph. Following and unfollowing live on GeoCities, not onchain, and are not stored with the name's records. Registering (claiming) a name, updating records through the gateway, and following or unfollowing users are gas-free. GeoCities never pays gas.

Sepolia testnet preview (chain id 11155111). Every name is a test name and may be reset.

Following and unfollowing users live on GeoCities. They are not onchain and not stored with the name's records. Both are authorized by the session cookie only: no signature, no gas. Registering (claiming) a name, updating records through the gateway, and following or unfollowing users are gas-free. GeoCities never pays gas. Names are full names only (<label>.geocities.eth or <tag>.<label>.geocities.eth). Today a bare label returns 400 invalid_name with detail: "name must be <label>.geocities.eth or <tag>.<label>.geocities.eth".

Request Auth Success
POST /v1/follow body { "target": "cto.geocities.eth" } session 201 when created, 200 when you already follow the name
DELETE /v1/follow/{name} session 200
GET /v1/follow/{name}/is-following session 200 { "name", "following": true|false }
GET /v1/follow/{name}/counts none (any origin, * CORS, no credentials) 200 { "name", "followers", "following" }
GET /v1/follow/{name}/followers?limit=&cursor= none 200 { "name", "followers": [{ "name" }], "nextCursor", "testName": true }
GET /v1/follow/{name}/following?limit=&cursor= none 200 { "name", "following": [{ "name" }], "nextCursor", "testName": true }

Notes:

  • Lists: limit is 1–50 (default 20). cursor is the opaque nextCursor from the previous page (null on the last page). A changed cursor, or a cursor from another name or list, is 400 invalid_request with reason invalid_cursor. Names are sorted A–Z.
  • Write limit: 30 per minute per account, counted inside one Worker isolate. Reads: 120 per minute per client, one isolate. Counts: 600 per minute per client, one isolate. A client whose requests land on several isolates can pass these.
  • Follows made by QA test accounts are stored but not counted or listed.

Samples:

POST /v1/follow            {"target":"cto.geocities.eth"}
201 {"follower":"mybot.geocities.eth","target":"cto.geocities.eth","following":true,"created":true}
(again) 200 {"follower":"mybot.geocities.eth","target":"cto.geocities.eth","following":true,"created":false}

DELETE /v1/follow/cto.geocities.eth
200 {"follower":"mybot.geocities.eth","target":"cto.geocities.eth","following":false,"removed":true}

GET /v1/follow/cto.geocities.eth/is-following
200 {"name":"cto.geocities.eth","following":false}

GET /v1/follow/cto.geocities.eth/counts
200 {"name":"cto.geocities.eth","followers":12,"following":3}

Errors: | Status | error | When | |---|---|---| | 400 | cannot_follow_self | Following or unfollowing your own name | | 400 | invalid_name (+ detail) | Not <label>.geocities.eth or <tag>.<label>.geocities.eth | | 400 | invalid_request | target is missing or not a string, or limit/cursor is bad | | 401 | unauthorized | No session (follow, unfollow, is-following) | | 404 | not_found | Well-formed but unknown name | | 429 | rate_limited | Too many requests | | – | (no error) | A duplicate follow is not an error. It returns 200 with "created": false. Unfollowing a name you don't follow returns 200 with "removed": false |