@@ -324,7 +324,7 @@ type ActivePoll = {pubkey: PubkeyHex, startedAt: Timestamp}
324324*pairRates : [RateEntry]
325325-- Per-key /auth/challenge counters (separate from `*challenges` capacity gate).
326326*challengeRates : [RateEntry]
327−-- Per-key counters for read-only lookups (presence, /messages/list).
327+-- Per-key counters for read-only lookups (presence).
328328*lookupRates : [RateEntry]
329329-- Per-peer counters for inbound federation calls.
330330*federationRates : [RateEntry]
@@ -377,7 +377,7 @@ type ActivePoll = {pubkey: PubkeyHex, startedAt: Timestamp}
377377-- ============================================
378378-- Public HTTP surface, grouped by audience:
379379-- AuthApi -- challenge/verify (client identity)
380−-- ClientApi -- /poll, /messages (send), /messages/list, /messages/status, presence lookup
380+-- ClientApi -- /poll, /messages (send), /messages/status, presence lookup
381381-- FederationApi -- inter-server gossip, forward (single + batch)
382382-- FederationPubkey -- exposes this server's federation Ed25519 public key
383383-- MaintenanceApi -- operator endpoints (prune, peer allow/block, admin)
@@ -393,7 +393,6 @@ route ClientApi where
393393 POST {cursor: Timestamp, generation: Int} /poll headers {authorization: Text, clientIp: Text} -> {events: [PollEvent], cursor: Timestamp, authorized: Bool, rateLimited: Bool, generation: Int, heartbeat: Bool, retryAfterMs: Int, cursorReset: Bool, hasMore: Bool, cursorStale: Bool, loadPct: Int} = Poll
394394 POST {messages: [{to: PubkeyHex, encryptedBlob: BlobHex}]} /messages headers {authorization: Text, clientIp: Text} -> {results: [{messageId: MessageIdHex, error: Text}], error: Text, retryAfterMs: Int} = SendMessages
395395 POST {to: PubkeyHex, messageId: MessageIdHex} /messages/status headers {authorization: Text, clientIp: Text} -> {status: Text, authorized: Bool} = MessageStatus
396− POST {offset: Int} /messages/list headers {authorization: Text, clientIp: Text} -> {messages: [{messageId: MessageIdHex, receivedAt: Timestamp}], authorized: Bool, count: Int, error: Text} = ListMessages
397396 GET /lookup/{pubkey: PubkeyHex} headers {authorization: Text, clientIp: Text} -> {server: ServerName, authorized: Bool, error: Text} = LookupPresence
398397 POST {pubkeys: [PubkeyHex]} /lookup/batch headers {authorization: Text, clientIp: Text} -> {results: [{pubkey: PubkeyHex, server: ServerName}], authorized: Bool, error: Text} = BatchLookupPresence
399398
@@ -1472,40 +1471,6 @@ handleMessageStatus = \to messageId authorization clientIp -> do
14721471 else if any fwds blobMatches then "forwarding" else "unknown"
14731472 yield {status: s, authorized: True {}})
14741473
1475−-- ============================================
1476−-- Handler: list
1477−-- ============================================
1478−-- Read-only mailbox peek by the recipient.
1479−
1480−-- POST /messages/list: paginated peek at the caller's mailbox without acking.
1481−-- Returns metadata only (no ciphertext) plus the total count.
1482−handleListMessages : Int -> Text -> Text -> IO {rw *globalRateCount, rw *globalRateWindowStart, r *sessions, clock} {authorized: Bool, count: Int, error: Text, messages: [{messageId: MessageIdHex, receivedAt: Int<Ms>}]}
1483−handleListMessages = \offset authorization clientIp -> do
1484− t <- now
1485− let mkErr = \e -> {
1486− messages: [],
1487− authorized: False {},
1488− count: 0,
1489− error: if e == "rate_limited" then e else ""
1490− }
1491− gateAuth authorization clientIp t mkErr (\pubkey -> do
1492− lim <- atomic (do
1493− rates <- *lookupRates
1494− let r = checkRate rates pubkey maxLookupRatePerKey lookupRateWindowMs t
1495− *lookupRates = r.entries
1496− yield r.limited)
1497− if lim
1498− then yield {messages: [], authorized: True {}, count: 0, error: "rate_limited"}
1499− else do
1500− msgs <- *messages
1501− let myMsgs = sortBy (\m -> m.receivedAt) (filter msgs (\m -> m.toKey == pubkey && t - m.receivedAt < messageMaxAge))
1502− let total = count myMsgs
1503− let page = pluck (takeRelation maxPollEvents (dropRelation (clamp 0 total offset) myMsgs)) (\m -> {
1504− messageId: messageIdOf m.encryptedBlob,
1505− m.receivedAt
1506− })
1507− yield {messages: page, authorized: True {}, count: total, error: ""})
1508−
15091474-- ============================================
15101475-- Handler: federation receive
15111476-- ============================================
@@ -2214,7 +2179,6 @@ api = serve Api where
22142179 Poll = \{cursor, generation, authorization, clientIp} -> handlePoll cursor generation authorization clientIp
22152180 SendMessages = \{messages, authorization, clientIp} -> handleSendMessages messages authorization clientIp
22162181 MessageStatus = \{to, messageId, authorization, clientIp} -> handleMessageStatus to messageId authorization clientIp
2217− ListMessages = \{offset, authorization, clientIp} -> handleListMessages offset authorization clientIp
22182182 LookupPresence = \{pubkey, authorization, clientIp} -> handleLookupPresence pubkey authorization clientIp
22192183 BatchLookupPresence = \{pubkeys, authorization, clientIp} -> handleBatchLookupPresence pubkeys authorization clientIp
22202184 RecvGossip = \{events, fromServer, requestTimestamp, authorization} -> handleRecvGossip events fromServer requestTimestamp authorization