Skip to main content
A signed-in, non-impersonated seller can directly search and get the retained Sessions Page access, including recorded storefront_rfp_v1 exchanges and their exact Proposal Pass and media-buy handoffs. When the server-owned compose-publication rollout selects that seller, it also admits storefront_compose_run_v1. Sellers may add a private note to a compose-run Session through an exact throughEventId; RFP feedback remains the native save_rfp_turn feedback field. Unqualified Session discovery and Apostra conversation reads remain restricted to a signed-in platform operator in a seller account. Buyer Session access is prepared but not active: no buyer source is currently activated. Until activation, Sessions stays out of buyer navigation, buyer Session search is denied, and tools/list for the active account remains authoritative.

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, and save_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 of tools/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 the archived 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:
The returned 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 a media_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:
  • snapshotThrough fixes the committed prefix being read.
  • pageNextAfter is present only when that prefix has another page.
  • resumeAfter remains 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.
Continue an existing snapshot with 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 Session get, 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

Use save_session with an exact Session ID, private note, and clientRequestId:
The note is an authored private event; it does not send a buyer message, amend the Apostra conversation or recorded RFP, alter a response in progress, update Playbook, approve an action, or create an evaluation. The same scoped request ID and same content reuses the retained note without appending a duplicate. Its delivery receipt remains 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. Use save_lesson to manage the workflow:
  • propose requires lesson with the typed kind, scope, payload, seller words, and one provenance mode. Teach this uses sessionId, turnOrEventId, and noteId, with seller words copied verbatim from that private note. A general proposal not taught by a note uses sourceRevision and omits the Session and note ids.
  • preview requires the proposed lessonId and a brief. It compares that brief with and without the proposed lesson, but writes no lesson, composition, provenance, cache entry, or history.
  • approve requires lessonId. Only a directly authenticated seller account administrator can approve; an impersonated administrator cannot approve.
  • retire requires lessonId and 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.
The tool is listed when a non-impersonated user can reach a Seller Account. Other sellers and buyers cannot read or use a seller’s private note or lesson. The lesson card shows whether the current caller can approve or retire it. Lessons accept only supported guidance kinds and limit each lesson to 500 characters. Pricing-posture and decline-behaviour lessons can be proposed and previewed, but cannot be activated.

Delivery status

This is retained-history and private-note infrastructure only. The code selects the Sessions Page only for accounts that the existing server checks authorise; it does not enrol accounts, claim deployment, enable message delivery, response approval, or completed evaluation work. The native source remains responsible for conversation execution and room permissions.