Seller Sessions workspace
Sessions is available to every seller. The seller navigation lists Sessions once, under Operate in Storefront; the Interview tool under Training links there, filtered to your own conversations with the assistant. From a selected buyer in Buyers it opens filtered to that buyer, for a signed-in seller who is not impersonating another user and owns that storefront; there is no rollout or enrolment step. It shows retained conversation history in ledger sequence as a chat-style timeline. Sellers can search the admitted history and narrow the one list with the Agent or Person, Source, and Lifecycle filters. Sessions are shown in Most recent order. An exact RFP request or response hands off to Proposal Pass once the seller’s response for that turn exists. The handoff is typed and authorised for the selected record; the workspace does not infer an RFP from displayed text. Brief and media-buy references remain visible in the timeline. The workspace shows an open action only when an event supplies the exact brief or media-buy reference; otherwise the chip remains a label.Sessions Page access
The Sessions Page has separate access checks. Code may select it for a signed-in seller who is not impersonating another user and owns the current storefront. Every seller has retained Sessions Page access, so no separate enrolment applies. The server makes that choice and checks access again for each Page call. Its access rules do not change generic Session access: source-qualified Storefront RFP reads remain available to the seller described below, while unqualified reads, Apostra reads, andsave_session
remain operator-only except for the selected compose-run note path.
The Page keeps authorised RFP exchanges separate from retained conversations. A
seller who owns the storefront can read an authorised RFP and open Proposal
Pass for its exact RFP and turn. Existing RFP write permissions still apply.
The Sessions Page includes recorded RFP exchanges in its default source set.
On larger screens, the RFP list remains beside the selected Proposal Pass; on
smaller screens, Back returns to that list. The selected RFP also keeps its
eligible native ledger actions, such as response linking, pairing and seller
feedback, beside that exact exchange; those actions remain subject to the
existing RFP write permissions. Each source keeps its own cursors and states.
When an exact native RFP turn is open, the ordinary bottom Apostra composer can
show that selected RFP and turn as removable private coaching context. It does
not send a buyer message, alter the RFP, create a retained Session note, or
change the composer into a shared room. The server checks the exact current
RFP/turn pair, seller access, and private room ownership again for every
composer send. Closing or replacing the selected exchange clears the context.
The Sessions tab includes Recorded RFP exchanges in the default search for
the seller who owns the storefront. The lists keep source-specific cursors, and
an RFP cannot create private notes or change the RFP through Sessions. Page
conversation search and reads require a signed-in seller who is not
impersonating another user, Page enablement for that seller, and current native
room access. Private notes remain an operator-only save_session operation
outside selected compose-run Sessions and show read-only when present in the
Sessions timeline. RFP history rechecks current seller ownership for every Page
and read. The Page fails closed when any of those checks is absent. The server
checks room sharing again for each conversation action. Existing read and write
permissions still apply.
When the server-owned compose-publication rollout selects a seller, that seller
can also select storefront_compose_run_v1. It returns captured compose
exchanges as retained history. Each recorded request shows a bounded summary of
the submitted brief, including the supplied advertiser or brand, channels,
countries, flight, budget, and formats. Each response shows the retained
buyer-facing opening words when they are available, a plain outcome (pitched,
passed, or asked for more information), products, bundles, proposals, and any
lessons that shaped it. The seller sees this as a private summary; it does not
change what the buyer received.
A pass with no matching products is retained too, so the seller can teach from
that decision. The server checks the rollout, seller ownership, and the exact
retained event on every search, read, and note. These seller-only summaries do
not create buyer access or change buyer projections.
RFP and conversation lists keep separate cursors and metrics. A seller can add
a private note to a selected compose-run turn only; the note is anchored to the
exact retained event. RFP Sessions remain read-only here: use the native
save_rfp_turn feedback field for feedback on an RFP turn.
Scope and access
search({"kind":"session"}), get({"kind":"session","id":"..."}),
and save_session({"action":"record_note", ...}) retain one canonical
owner. A signed-in, non-impersonated seller may use search with
filter.sessionSource: "storefront_rfp_v1", or with
"storefront_compose_run_v1" when the staged compose rollout has selected
their seller. They may get only a matching source Session ID. Each source
independently rechecks current seller ownership on every page and read.
Unqualified discovery and Apostra conversation reads still require a platform
operator acting in a seller account. Compose-run notes are available to the
owning seller only when that source is selected and published; RFP feedback uses
the native RFP action. Operator access does not bypass source permissions. A
member can read their own Apostra room; a shared
room is readable only while the server’s current room-sharing policy permits
that member. The server checks that policy again for every page and note retry.
Changing a participant, RFP owner, or private-practice marker does not grant
access.
Generic intake, buyer message delivery, lifecycle updates, approvals, chat
execution, and evaluations are not available through this admitted slice.
Buyer read boundary
Buyer Session access is staged by source. It is not active today because no buyer source has been activated. When an approved source is activated, Sessions appears in the buyer rail only for a signed-in, non-impersonated buyer account where the server has enabled buyer Session reads. The browser does not evaluate that rollout decision. A buyer sees only the buyer-visible request and response records that the activated source authorises for that exact buyer relationship. A buyer cannot see seller private notes, coaching, lessons, internal reasoning, or seller-only summaries. Buyers cannot add notes, edit a proposal, send a Session message, or use lessons. The buyer list keeps Source and Lifecycle filters; it does not show the Agent or Person filter because that distinction does not change a buyer’s available records.Buyer record chips
Buyer record chips are not available yet. When buyer Session reading is enabled for an approved source, a proposal or media-buy chip opens only the exact admitted version recorded in that Session. A foreign, revoked, removed, or mismatched record shows as unavailable. The navigation variant stays out oftools/list until that buyer Session rollout is enabled.
When a source is approved for buyer reads, a signed-in buyer who is not
impersonating another user will be able to read only exchanges with a recorded
counterparty membership and a current relationship that the source verifies.
The source will check that relationship again for every search page and read. A
buyer will never see another buyer’s exchange or an unrelated seller’s exchange.
A revoked relationship will return no result, and get will not reveal whether
a Session exists.
The service returns only events explicitly classified as buyer-visible. It
withholds seller private notes, coaching, agent-only events, Apostra context,
internal reasoning, and any event classification not explicitly approved for
buyers, even if a source mistakenly adds one during read enrichment. Buyers
cannot use save_session, add private notes, edit proposals, send a buyer
message, or use seller coaching controls. Sources that do not yet implement the
buyer relationship boundary are empty to buyers, rather than falling back to
their seller read path.
Find and read retained history
Only conversations with a complete-history publication admission appear in Session search. A retained root alone is not admission. Search and get never create an Apostra room, import history, allocate an event position, or repair source data. An eligible newly created Storefront RFP can admit its recorded initial request to the retained timeline. Historical RFP rows are not imported by a read: until a bounded server-side import admits their recorded history, they remain RFP rows and have no Session result. After admission, later recorded RFP events continue in the same retained sequence. RFPs owned by private practice never appear as Sessions. No filter searches admitted Apostra conversations, RFPs, and standalone media-buy Sessions for an operator. Lifecycle-filtered searches retain their existing Apostra/RFP behavior; media buys do not support lifecycle filtering. A text query or thearchived lifecycle filter selects the authorized Apostra source only; it
never sends that request to the RFP source. A seller’s direct RFP read must select
filter.sessionSource: "storefront_rfp_v1". That source accepts exact
filter.buyer and filter.advertiser discovery values. They are trimmed
strings matched without case-folding or alias resolution against any of
storefront_rfp.origin.buyer,
storefront_rfp.origin.preset.buyer, and the latest recorded turn’s
request.dimensions.buyer (and the equivalent advertiser paths). There is
no precedence: a row matches when any exact recorded path matches. Missing
values do not match. The latest-turn path is deliberately the current recorded
dimension, not a search across every historical participant or turn.
Those buyer and advertiser values are discovery metadata only. They are not
customer, user, or advertiser-account identities and do not grant access.
Sessions never derive an identity from brief, message, or discovery text.
An empty
advertiserIds list does not constrain a search. When the list is
non-empty and callers also supply advertiserId, every source uses their
intersection. The singular ID must occur in the list; if it does not, the
search returns no Sessions.
When a mixed search includes buyerAccountIds, Sessions skips the unsupported
Apostra source and returns matching RFP and media-buy results. actorKind: "agent" selects
recorded AdCP/RFP and media-buy activity, while actorKind: "human" selects Apostra
conversations; classifications are source-derived rather than inferred from
text. RFP turns expose deterministic readable text from the recorded brief,
budget, flight, audience, and proposal commercial facts; no model call is made
when a timeline is read.
A storefront compose Session carries sandbox: true when its brief came from a
buyer’s sandbox advertiser. It sits on the Session object in get and on each
search result with kind: "session", and it is absent otherwise, never
false. It is read-only and is not a filter or an input. Sandbox Sessions stay
in every list. A Session recorded before Apostra noted a brief’s origin has no
marker.
With the explicitly selected Storefront RFP source, one Session purpose value
and updatedAfter are supported. Live status, attention, operator domain, and
transport remain rejected rather than becoming a partial RFP search. A rejected
filter never produces a partial unfiltered page.
storefront_media_buy_v1 exposes retained, seller-operator-only Sessions for
media buys that are not linked to an admitted RFP Session. It records the
buyer-facing media-buy identifier on every event so the media-buy document can
be opened from the timeline. The timeline records each forwarded media-buy
creation, update, and creative sync request and response. Search supports the recorded agent classification
and native buyer and advertiser identities; it does not infer identity from
free-form request fields. Buyer reads remain unavailable.
Media-buy Sessions cover only media buys created or replayed after this release;
earlier media buys will not appear until the historical import lands. A seller’s
unqualified Session search includes retained standalone media-buy Sessions. A
linked media buy remains in its RFP Session and is never returned as a second,
standalone result. A caller can still select storefront_media_buy_v1 directly.
Mixed-source search visits admitted Apostra conversations first, then admitted
RFPs, then retained media buys. This is source order, not a
global chronology or relevance ranking. Each source uses its immutable retained
publication order, and a page contains rows from one source only. A short Apostra
page can therefore retain a continuation for RFPs or the media-buy source. The
signed cursor binds the account, actor, access policy, canonical filters and
limit, the selected source versions and order, and one retained-publication
scope captured at the first page. That scope contains a committed publication-
sequence ceiling and a generation. Each source reads membership against that
fixed scope rather than mutable native activity. A Session first retained after
the ceiling is excluded until a fresh search. An old cursor or a cursor whose
generation no longer matches must restart rather than be reinterpreted.
Each continuation binds the account, actor, room-sharing policy, complete
canonical filter set, selected source version and one retained-publication
scope. Each continuation also binds the complete matching retained set for the
source it is reading at that ceiling. For Apostra, that includes supported
lifecycle and current room access. For an RFP continuation, it includes the
current seller owner, private-practice marker, lifecycle, and selected latest
buyer/advertiser dimensions. If one of those changes the matching set between
pages, the next page
requires a fresh search rather than silently skipping or adding a result.
Native activity that does not change the set, and publications after the
ceiling, do not invalidate the traversal.
When an admitted RFP turn becomes terminal, the native turn and its retained
terminal action are written together. If that retained write cannot complete,
the native terminal transition is rolled back. An unadmitted RFP remains
native-only until the bounded importer admits its complete history.
Search cursors are separate from the event cursors returned by get. Current
account and native source access are checked again on every page.
For example, this discovers one seller-owned retained RFP source without
claiming a buyer-account relationship:
sessionId can be read with get(kind: "session", id: ...).
Its request, response, and terminal events remain structured_only: request
and response text can be null, while each event carries its exact RFP and
turn references and version digest. Use the existing
get(kind: "rfp_turn", id: "...") owner for the authoritative shared Brief
or Proposal document and representation references. A multi-turn RFP therefore
returns recorded request/response/action events in retained sequence, not a
fabricated chat transcript.
Open a linked Proposal Pass
When a retained Session shows a linked RFP request or response with both an RFP ID and a turn ID, a seller can select Open exact Proposal Pass to open that exact turn. Proposal Pass checks the seller’s current access again before it opens; seeing a Session link does not grant new access. Representation links and incomplete references stay read-only. They do not offer an open action because they do not identify an exact RFP turn. If the existing Proposal Pass bridge cannot open an eligible link, the retained Session stays available and shows a retry action. Retrying does not alter the RFP, representation, or retained record.Sessions Page hand-offs
The Sessions Page is available to every seller. From an eligible Session event, it can open the original brief for a recorded RFP request that carries a brief-artifact evidence reference. It can also open a media-buy timeline when an event carries amedia_buy downstream reference.
These are Page-only hand-offs, not agent tools, so they do not appear in
tools/list. Opening a brief requires current ownership of the storefront,
just as recorded RFP history does. The media-buy timeline hand-off rechecks the
seller’s access for that exact buy. An absent or inaccessible reference returns
NOT_FOUND or ACCESS_DENIED; the Page does not launch a timeline for it.
No suitable inspected source currently links a buyer account to these raw
dimensions or captures a buyer-to-seller human transcript for this Session
contract. That linkage, human-capture adapter, media-buy history, and
sync-creatives history remain separate requirements; private Apostra coaching is
not substituted for any of them.
get returns an immutable page of retained events and three cursor values:
snapshotThroughfixes the committed prefix being read.pageNextAfteris present only when that prefix has another page.resumeAfterremains at that prefix’s boundary, including an empty or final page, so a later poll can receive publications that arrived while pages were being read.
pageNextAfter as after and the original
snapshotThrough as through. Once it is consumed, poll with resumeAfter
as after and no through. Cursors identify positions, not permission:
current account and native source access are rechecked on every read.
Complete result boundary
On a successful retained Sessionget, both the text-only MCP channel and
structuredContent carry the same model-facing Session page: event bodies,
evidence and locators, participant/link-decision context, approvals,
capabilities, and cursor values. Event text is fenced as untrusted data.
Widget metadata carries the complete retained text.
The complete returned MCP result, including both channels, is limited to
1,000,000 characters. Retained message text supports up to 60,000 characters.
The widget receives the complete retained text; model-facing event text is
limited to 32,000 characters, including its untrusted-content fence, with an
explicit marker when it is shortened. If the complete result does not fit,
get returns a VALIDATION_ERROR and attaches no Session page. For a multi-event page, retry
the same Session ID and after/through boundary with limit: 1 or a smaller
valid limit. Continuation requests may reduce the page limit while keeping the
same snapshot; increasing it requires a fresh read without cursors. The Session
widget retries an oversized page with one event and keeps that smaller limit
for subsequent pages. If a one-event minimum page still exceeds the boundary, repeating
the same request cannot recover it: this read has no text-offset continuation.
Historical import is an explicit server-side, bounded operation. Apostra import
handles at most 100 native messages, and Storefront RFP import handles at most
100 source turns, in one transaction. A fresh Apostra room may admit only with
its first native message. An older room can continue native conversation work
while unadmitted; if its history exceeds the bound or its retained root is
partial, Session search, get, and notes remain unavailable and the stored
timeline is not rewritten. Each import fails rather than returning partial
reconstructed history. Later native publications and private notes use the
same retained sequence. A message, recorded RFP event, or note never changes
an already returned event.
Add a private coaching note
Usesave_session with an exact Session ID, private note, and
clientRequestId:
null. Reusing that key with different content
fails. If current room or seller access has been revoked, both a new write and
its retry fail.
Teach from a Session note
Sellers can select Teach this on a saved private note. The note’s seller words are used to create a proposed lesson. A proposed lesson changes nothing until an eligible seller administrator approves it. Usesave_lesson to manage the workflow:
proposerequireslessonwith the typed kind, scope, payload, seller words, and one provenance mode. Teach this usessessionId,turnOrEventId, andnoteId, with seller words copied verbatim from that private note. A general proposal not taught by a note usessourceRevisionand omits the Session and note ids.previewrequires the proposedlessonIdand abrief. It compares that brief with and without the proposed lesson, but writes no lesson, composition, provenance, cache entry, or history.approverequireslessonId. Only a directly authenticated seller account administrator can approve; an impersonated administrator cannot approve.retirerequireslessonIdand has the same administrator rule. A retired lesson no longer shapes future matching compositions and cannot be approved again. Propose a new lesson to use that guidance again.