Skip to main content

Search Proxy (Cloudflare Worker)

  • Config: components/search_proxy/wrangler.toml
  • Source: components/search_proxy/src/

The main search API. Routes search queries to Marqo via service bindings, with authentication, caching, settings management, and metrics.

Worker Names

EnvWorker NameDomain
Stagingstaging-ecom-apistaging-ecom.dev-marqo.org
Preprodpreprod-ecom-apiecom.preprod-marqo.org
Prodprod-ecom-apiecom.marqo-ep.ai

Bindings

BindingTypePurpose
KVKV NamespaceIndex settings (populated by Settings Exporter Lambda)
KV_QCFGKV NamespaceQuery config overrides (populated by Admin Lambda)
MARQO_WORKERService BindingMarqo search backend (global-worker)
PIXEL_WORKERService BindingAnalytics pixel tracking
AGENTIC_SEARCH_WORKERService BindingAI-powered conversational search

Request Flow

  1. Extract API key from X-API-Key or Shopify proxy auth
  2. Validate API key with control plane gateway
  3. Load index settings from KV
  4. Apply query overrides from KV_QCFG
  5. Check for redirects (parallel with search)
  6. Call Marqo via MARQO_WORKER service binding
  7. Transform and return results
  8. Enqueue metrics to SQS (async via waitUntil)

Key Endpoints

PathMethodPurpose
/searchPOSTMain search
/search/compositePOSTMulti-query search
/recommendations/similarPOSTSimilar product recs
/recommendations/complementaryPOSTComplementary recs
/recommendations/for-youPOSTPersonalized recs
/search/suggestionsPOSTAutocomplete
/collectionsPOSTCollection-filtered search
/agentic/searchPOSTAI conversational search
/agentic/chatPOSTMulti-turn AI chat

External Dependencies

ServiceHowCredentials
MarqoService binding to global-workerN/A (internal)
SQS (metrics)AWS SDK via IAM userAWS_ACCESS_KEY_ID/SECRET from Secrets Manager
DDB (redirects)AWS SDK via IAM userSame IAM user as SQS
KV (settings)Cloudflare KV bindingN/A (built-in)
Control plane APIHTTP to API GatewayIAM or API key

Typical Investigation Paths

Search returning errors:

  1. Tail worker logs: npx wrangler tail {env}-ecom-api
  2. Check if settings exist in KV for the account
  3. Check Marqo worker health via service binding

Stale search results / settings not applying:

  1. Read KV key for the account: npx wrangler kv key get --namespace-id {id} "{system_account_id}"
  2. Compare with DDB source: query EcomIndexSettingsTable for the account pk
  3. Check settings exporter Lambda logs (DDB stream consumer)

High latency:

  1. Check Marqo backend health
  2. Check CloudWatch dashboard for p99 latency widgets
  3. Look for slow queries in worker logs

Relevance trigger not appearing in responses:

relevanceScore is omitted silently from the response whenever any precondition fails. Walk this checklist in order:

  1. Client must pass "relevanceScore": true in the request body. Without the flag, scoring is never invoked (zero overhead).
  2. Index settings in KV must include relevance_trigger_config.model_id. Read the KV record for the account and confirm the field is present:
    npx wrangler kv key get --namespace-id <id> "<system_account_id>-<index_name>" | jq .relevance_trigger_config
  3. The model JSON must exist in KV under relevance_model:<model_id>. Look for relevance_model_not_found warnings in worker logs (npx wrangler tail {env}-ecom-api).
  4. Query type — image queries, wildcard (*), multi-term/weighted objects, and empty queries are skipped by design.
  5. Hit count — fewer than 3 hits returned causes the scorer to skip (score-variance features need multiple data points).
  6. Errors — look for relevance_score_call_failed warnings (emitted by the search.ts call sites when the scorer throws). The scorer itself propagates errors to the call site, which is wrapped in try/catch and returns null on any exception.
  7. Successful scoring logs relevance_score_computed with relevance_score, relevance_scoring_ms, and model_id fields.

To enable the feature for a new index, follow the enable-relevance-trigger runbook.