vtex.search-session is a thin transform service that converts shopper-side session inputs into the storefront search.facets value consumed by Intelligent Search. It owns no persistent data.
Session namespace contract
The contract is declared in vtex.session/configuration.json:
_19{_19 "search": {_19 "input": {_19 "public": [_19 "facets",_19 "postalCode",_19 "geoCoordinates",_19 "country",_19 "region_id"_19 ],_19 "profile": ["email", "isAuthenticated"],_19 "storefront-permissions": ["organization"]_19 },_19 "output": {_19 "search": ["facets"],_19 "public": ["postalCode", "country", "geoCoordinates"]_19 }_19 }_19}
Inputs are read by transform from the request body (it is called by the VTEX session runtime). Outputs are written back to the session in the search.facets.value and public.* slots.
Request/response shape
POST /_v/search/session/transform/ body:
_16type Body = {_16 public: {_16 facets: { value: string } // "key=value;..." (mixed)_16 region_id: { value: string } // base64 "vtex:BRA:0000000"_16 postalCode: { value: string }_16 country: { value: string }_16 geoCoordinates: { value: string } // "lon,lat" (typo from checkout API)_16 }_16 'storefront-permissions': {_16 organization: { value: string } // B2B ACL key_16 }_16 profile: {_16 email: { value: string }_16 isAuthenticated: { value: string } // 'true' | 'false'_16 }_16}
Response (in ctx.response.body):
_11{_11 search: {_11 facets: { value: string } // serialized via stringifyFacets()_11 },_11 public: {_11 // Only set when region_id is the source of truth:_11 postalCode?: { value: string }_11 country?: { value: string }_11 geoCoordinates?: { value: string }_11 }_11}
Transform pipeline
_15POST /_v/search/session/transform/_15 ├─► checkProviderImplementation_15 │ └─ ctx.hasImplementationApp = apps has `vtex.search-segment-graphql@0.1.1`_15 └─► transform_15 ├─ parseFacetsString(public.facets.value) → SelectedFacet[] (excludes delivery-promises keys)_15 ├─ if hasImplementationApp:_15 │ └─ graphqlServer.query(searchSegmentQuery, { userEmail, isAuthenticated, selectedFacets })_15 │ → selectedFacetsResult (overrides default facets)_15 ├─ if storefront-permissions.organization: append { key: 'accesscontrollist', value: organization }_15 ├─ deliveryPromises(ctx, body):_15 │ ├─ Source of truth priority: public > facets (zip-code, country, coordinates)_15 │ ├─ Fallback: parse region_id (base64 "vtex:BRA:0000000") + checkout.getGeocoordinates_15 │ └─ logisticShipping.deliveryZones / pickupPoints → { deliveryZonesHash, pickupPointsHash }_15 ├─ Append deliveryZonesHash / pickupPointsHash to selectedFacetsResult_15 └─ Respond { search.facets: stringifyFacets(...), public: { ...region } }
Facets wire format
The facets string flows through three pure utilities in node/utils.ts:
| Function | Role |
|---|---|
parseFacetsString(str) | Splits "k=v;..." into SelectedFacet[], excluding delivery-promises keys (zip-code, country, coordinates). |
parseDeliveryPromisesInput(str) | Same input, only keeps delivery-promises keys → Record<string, string>. |
stringifyFacets(facets) | Serializes SelectedFacet[] back to "k=v;k=v;" (trailing ;). |
Outbound clients
| Client | File | Talks to | Policy |
|---|---|---|---|
graphqlServer | node/clients/graphqlServer.ts | vtex.graphql-server:resolve-graphql (in-account GraphQL) | vtex.graphql-server:resolve-graphql |
logisticShipping | node/clients/logisticShipping.ts | portal.vtexcommercestable.com.br/api/logistics-shipping/* | outbound-access (declared in manifest.json) |
checkout | node/clients/checkout.ts | portal.vtexcommercestable.com.br/api/checkout/pub/* (geocoordinates resolution) | outbound-access |
@vtex/api default options: retries: 2, timeout: 6000ms (MEDIUM_TIMEOUT_MS).
Test surface
| File | Covers |
|---|---|
node/__tests__/utils.test.ts | parseFacetsString, parseDeliveryPromisesInput, stringifyFacets — wire-format contract |
node/__tests__/trasnform.test.ts | Legacy / stale — references an older transform shape that mutated body.public.facets.value in place. Current transform returns a new shape via ctx.response.body. Slated for rewrite. |