Menu
Client Methods

Unified Search

Search across all entity types in a single call.

Search across all entity types (profiles, agent_playbooks, user_playbooks) in a single call. The server prepares the query, then retrieves the requested entity types.

Async applications can call await client.search_async(...) with the same request fields and response model. It uses native async HTTP, applies the client's total timeout, and preserves task cancellation.

The server applies a five-second deadline to POST /api/search, including authentication, billing checks, retrieval and response preparation. If that budget expires before the complete response is accepted, it returns HTTP 504 with detail: "Request timeout", reason: "search_deadline" and a correlation_id; no partial results are returned. If the five-second deadline is disabled, the server's existing HTTP backstop still applies and reports reason: "backstop_timeout". Slow or oversized request bodies are bounded before authentication/search worker admission. Once a complete successful response is accepted, the server finishes durable exposure recording before releasing it. The finalizer must start and accept the response within the original budget; queue expiry returns 504 without served-state changes. Accepted finalization has one additional five-second commit budget and waits for actual cleanup instead of returning a timeout after a durable write. Total latency can therefore reach ten seconds plus cleanup. With the search deadline disabled, finalization uses the remaining HTTP backstop. Session deduplication, applied-learning metering, and completion observers run only for accepted responses. A disconnect prevents callbacks that have not claimed execution; already active callbacks may finish. This preserves durable work and does not guarantee that the client received the response. Client-to-server network time is additional. Under sustained stalled work, the server can return HTTP 503 rather than admit more searches. Total storage failure also returns 503. Usable partial results remain 200, with degradation metadata; an empty successful result is distinct from unavailable storage.

Self-hosted operators can disable deadline enforcement with REFLEXIO_SEARCH_DEADLINE_ENABLED=false; timing and connection recovery remain active. Direct embedded Python calls do not acquire this HTTP deadline.

When an agent playbook is returned, user_playbooks omits source user playbooks already represented by that agent playbook. The server does not refill suppressed user playbooks, so user_playbooks may contain fewer than top_k items.

Python
response = client.search(
    query="user preferences",
    user_id="user_123",
    session_id="session_001",
    source="api",
    top_k=5,
    threshold=0.45,
    tags=["preferences", "support"],
)
Terminal
curl -X POST "${REFLEXIO_URL:-https://www.reflexio.ai}/api/search" \
  -H "User-Agent: my-agent-reflexio" \
  -H "Authorization: Bearer $REFLEXIO_API_KEY" \
  -H "Content-Type: application/json" \
  --data @- <<'JSON'
{
  "query": "user preferences",
  "user_id": "user_123",
  "session_id": "session_001",
  "source": "api",
  "top_k": 5,
  "threshold": 0.45,
  "tags": ["preferences", "support"]
}
JSON
PropTypeDefaultDescription
querystr—Search query text
top_k?int5Maximum results per entity type, from 1 through 100.
threshold?floatmodel-specificSimilarity threshold for the vector arm. Omit it to use the embedding model's default.
agent_version?str—Filter by agent version (agent_playbooks, user_playbooks)
playbook_name?str—Filter by playbook name (agent_playbooks, user_playbooks)
user_id?str—Filter by user ID (profiles, user_playbooks) and identify the user for retrieval-experiment assignment. Required for agent traffic while an experiment is active. At most 255 characters.
source?str—Filter every selected entity type by exact source. Agent playbooks match when at least one linked source user playbook has that source. Omit, pass null, or pass an empty string to disable source filtering.
request_id?str—Optional caller correlation ID for the search turn. At most 255 characters. Published exposure evidence binds to the actual publish request; search does not persist exposure records.
session_id?str—Optional caller session ID for the search turn. At most 255 characters. Enables session-scoped result deduplication and binds a returned exposure receipt to this session; publish that receipt in the same session.
interaction_id?int—Optional positive integer (minimum 1) used to attribute served results to the caller interaction.
tags?list[str]—Match entities having any requested tag (OR semantics). Omit or pass an empty list to disable tag filtering.
entity_types?list[str]—Entity types to search. Valid values: "profiles", "user_playbooks", "agent_playbooks". When unset, all are searched.
agent_playbook_status_filter?list[PlaybookStatus | str]—Agent-playbook approval statuses to include
enable_reformulation?boolfalseEnable query reformulation for improved search results
enable_agent_answer?boolfalseEnable agentic answer synthesis when the configured search backend supports it
conversation_history?list[ConversationTurn]—Prior conversation turns for context-aware query reformulation
search_mode?SearchMode | str—Search mode: "vector", "fts", or "hybrid". Accepts SearchMode enum or string. When unset, the server uses its configured default ("hybrid").

Example:

Python
# Basic unified search
response = client.search(query="response quality issues", session_id="session_001")

print(f"Profiles: {len(response.profiles)}")
print(f"Agent Playbooks: {len(response.agent_playbooks)}")
print(f"User Playbooks: {len(response.user_playbooks)}")
if response.reformulated_query:
    print(f"Reformulated query: {response.reformulated_query}")

for profile in response.profiles:
    print(f"  Profile: {profile.content[:80]}...")

for playbook in response.agent_playbooks:
    print(f"  Playbook: {playbook.content[:80]}...")

# Search with filters
response = client.search(
    query="handling edge cases",
    session_id="session_002",
    agent_version="v2.1.0",
    tags=["reliability", "support"],
    top_k=10,
    threshold=0.4
)

# Search filtered by user
response = client.search(
    query="product preferences",
    user_id="user_123",
    session_id="session_003",
    top_k=5
)
Terminal
curl -X POST "${REFLEXIO_URL:-https://www.reflexio.ai}/api/search" \
  -H "User-Agent: my-agent-reflexio" \
  -H "Authorization: Bearer $REFLEXIO_API_KEY" \
  -H "Content-Type: application/json" \
  --data @- <<'JSON'
{
  "query": "response quality issues",
  "session_id": "session_001"
}
JSON

curl -X POST "${REFLEXIO_URL:-https://www.reflexio.ai}/api/search" \
  -H "User-Agent: my-agent-reflexio" \
  -H "Authorization: Bearer $REFLEXIO_API_KEY" \
  -H "Content-Type: application/json" \
  --data @- <<'JSON'
{
  "query": "handling edge cases",
  "session_id": "session_002",
  "agent_version": "v2.1.0",
  "tags": ["reliability", "support"],
  "top_k": 10,
  "threshold": 0.4
}
JSON

curl -X POST "${REFLEXIO_URL:-https://www.reflexio.ai}/api/search" \
  -H "User-Agent: my-agent-reflexio" \
  -H "Authorization: Bearer $REFLEXIO_API_KEY" \
  -H "Content-Type: application/json" \
  --data @- <<'JSON'
{
  "query": "product preferences",
  "user_id": "user_123",
  "session_id": "session_003",
  "top_k": 5
}
JSON

Published exposure receipts

Enterprise user-playbook search results may include an opaque exposure_receipt. Preserve it with the matching user-playbook ID in the Assistant interaction’s retrieved_learnings when publishing. The server records exposure atomically with that interaction, using the version served by search. Search itself writes no exposure ledger row. Claude-smart and OpenClaw preserve receipts automatically.

Missing or rejected receipts remain incomplete published evidence; they do not recover served-version fingerprints from the current playbook. Receipts describe client-declared published injections, not proof of actual causal use.