---
title: "Ambient Sync"
method: GET
path: "/api/me/sync"
tags: ["me"]
---

# Ambient Sync

`GET /api/me/sync`

## Request

- Base URL: `https://app.thinqos.com` (the document declares no server; this is the origin it was published from)
- URL: `https://app.thinqos.com/api/me/sync`
- Auth: none declared

Every ambient badge surface in one cheap round trip (TOS-3494).

Replaces the ambient half of the always-on ``GET /api/me/events`` stream.
That stream is a held HTTP request, and Cloud Run bills request-based CPU at
9.6x the idle rate for the whole time any request is in flight, so an
open-but-silent stream costs the same as hard compute. Measured 2026-08-22:
563 streams x 228s mean = 128,394 request-seconds/day, **51% of all billable
instance time on awen-api**, overwhelmingly from tabs nobody was looking at.

Why ONE endpoint rather than four polls. The four ambient surfaces (nav
unread badge, notification bell, agents "needs review" badge, chat sidebar)
each have a perfectly good REST endpoint already. Polling all four costs
four auth passes, four ``get_db`` sessions and four middleware traversals per
tick, and the measured floor for any request here is ~0.25-0.6s regardless
of how trivial its work is. Consolidating is roughly a 3x saving on top of
the ~30x from not holding the stream open. constraint-intelligence runs the
unconsolidated version (3-5 sequential round trips per tick) and lists it as
a known defect; this is the fixed shape, not a port of theirs.

``since`` is optional. Omitted, this is a bootstrap returning current state
with no ``changed_chat_ids``. Supplied, ``changed_chat_ids`` carries chats
whose activity moved since then. The comparison is ``>=`` (matching the
existing ``activity_since`` filter on ``GET /api/chats``), so the boundary
chat can repeat across consecutive polls; consumers must treat the list as a
set of "refetch this" hints and not as an append log.

Sends ``ETag``/``304``. The overwhelmingly common outcome is that nothing
changed, and a 304 skips the response body: FastAPI clears it for any status
that may not carry one, so the wire form is a bodiless, Content-Length-less
304 per RFC 7232. It does NOT skip serialization - the payload is still
encoded and then discarded - and it does NOT skip the queries below, which is
deliberate: a cheaper "has anything
changed" probe would need its own high-water-mark column, and each query
here is already indexed and cheap. Revisit only if measurement says these
queries, rather than the request floor, are the cost.

## Query parameters

- `since` string, date-time, nullable
- `cursor` string, nullable

## Headers

- `x-impersonate-identity-id` string, nullable

## Response `200`

Successful Response

- AmbientSyncResponse: One round trip covering every ambient badge surface (TOS-3494). Deliberately returns COUNTS and CHANGED IDS, not hydrated payloads. Each consumer already owns a fetch for its own detail; what it lacked was a cheap way to learn whether that fetch is worth making. Returning the detail here instead would recreate the fully-hydrated chat-list read this endpoint exists to avoid, and would couple four independent surfaces into one response shape that every one of them would have to agree on forever.
  - `cursor` string, required
  - `since_watermark` string, date-time, required
  - `events` RealtimeEventOut[]
    - `seq` integer, required
    - `topic` string, required
    - `kind` string, required
    - `entity_type` string, nullable
    - `entity_id` string, nullable
    - `version` integer, nullable
    - `hint` object, nullable
  - `events_truncated` boolean
  - `total_unread` integer, required
  - `self_unread` integer, required
  - `notification_open_count` integer, required
  - `notification_latest_at` string, date-time, nullable
  - `agent_pending_total` integer, required
  - `agent_pending_by_agent` object
  - `skills_pending_approval_count` integer
  - `mind_attention_total` integer
  - `connection_requests_pending_count` integer
  - `connection_accepted_unseen_count` integer
  - `admin_pending_total` integer
  - `changed_chat_ids` string[]
  - `inbound` AmbientSyncInboundMessage[]
    - `message_id` string, required
    - `chat_id` string, required
    - `sender_id` string, nullable
    - `sender_display_name` string, nullable
    - `role` string, required
    - `preview` string, nullable
    - `preview_markdown` string, nullable
  - `added_to_chats` AmbientSyncAddedToChat[]
    - `chat_id` string, required
    - `actor_id` string, nullable
    - `actor_display_name` string, nullable

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/thinqos/apis/thinqos-api.md) · [All operations](https://skmtc.dev/thinqos/apis/thinqos-api/llms.txt) · [OpenAPI document](https://skmtc.dev/thinqos/apis/thinqos-api/revisions/5387b4ded614?raw)
