---
title: "Search V1"
method: POST
path: "/v1/memory/search"
tags: ["v1", "Memory"]
---

# Search V1

`POST /v1/memory/search`

Search through memories with authentication required.
    
    **Authentication Required**:
    One of the following authentication methods must be used:
    - Bearer token in `Authorization` header
    - API Key in `X-API-Key` header
    - Session token in `X-Session-Token` header
    
    **Response Format Options**:
    Choose between standard JSON or TOON (Token-Oriented Object Notation) format:
    - **JSON (default)**: Standard JSON response format
    - **TOON**: Optimized format achieving 30-60% token reduction for LLM contexts
      - Use `response_format=toon` query parameter
      - Returns `text/plain` with TOON-formatted content
      - Ideal for LLM integrations to reduce API costs and latency
      - Maintains semantic clarity while minimizing token usage
      - Example: `/v1/memory/search?response_format=toon`
    
    **Custom Schema Support**:
    This endpoint supports both system-defined and custom user-defined node types:
    - **System nodes**: Memory, Person, Company, Project, Task, Insight, Meeting, Opportunity, Code
    - **Custom nodes**: Defined by developers via UserGraphSchema (e.g., Developer, Product, Customer, Function)
    
    When custom schema nodes are returned:
    - Each custom node includes a `schema_id` field referencing the UserGraphSchema
    - The response includes a `schemas_used` array listing all schema IDs used
    - Use `GET /v1/schemas/{schema_id}` to retrieve full schema definitions including:
      - Node type definitions and properties
      - Relationship type definitions and constraints
      - Validation rules and requirements
    
    **Recommended Headers**:
    ```
    Accept-Encoding: gzip
    ```
    
    The API supports response compression for improved performance. Responses larger than 1KB will be automatically compressed when this header is present.
    
    **HIGHLY RECOMMENDED SETTINGS FOR BEST RESULTS:**
    - Set `enable_agentic_graph: true` for intelligent, context-aware search that can understand ambiguous references
    - Use `max_memories: 15-20` for comprehensive memory coverage
    - Use `max_nodes: 10-15` for comprehensive graph entity relationships
    - Use `response_format: toon` when integrating with LLMs to reduce token costs by 30-60%
    
    **Agentic Graph Benefits:**
    When enabled, the system can understand vague references by first identifying specific entities from your memory graph, then performing targeted searches. For example:
    - "customer feedback" → identifies your customers first, then finds their specific feedback
    - "project issues" → identifies your projects first, then finds related issues
    - "team meeting notes" → identifies your team members first, then finds meeting notes
    - "code functions" → identifies your functions first, then finds related code
    
    **Role-Based Memory Filtering:**
    Filter memories by role and category using metadata fields:
    - `metadata.role`: Filter by "user" or "assistant" 
    - `metadata.category`: Filter by category (user: preference, task, goal, facts, context | assistant: skills, learning)
    
    **User Resolution Precedence:**
    - If both user_id and external_user_id are provided, user_id takes precedence.
    - If only external_user_id is provided, it will be resolved to the internal user.
    - If neither is provided, the authenticated user is used.

## Query parameters

- `max_memories` integer — HIGHLY RECOMMENDED: Maximum number of memories to return. Use at least 15-20 for comprehensive results. Lower values (5-10) may miss relevant information. Default is 20 for optimal coverage.
- `max_nodes` integer — HIGHLY RECOMMENDED: Maximum number of neo nodes to return. Use at least 10-15 for comprehensive graph results. Lower values may miss important entity relationships. Default is 15 for optimal coverage.
- `response_format` 'json' | 'toon' — Response format options for API endpoints. - json: Standard JSON format (default) - toon: Token-Oriented Object Notation format for 30-60% token reduction in LLM contexts

## Headers

- `Accept-Encoding` string

## Request body

- SearchRequest — Search request parameters
  - `query` string, required — Detailed search query describing what you're looking for. For best results, write 2-3 sentences that include specific details, context, and time frame. Examples: 'Find recurring customer complaints about API performance from the last month. Focus on issues where customers specifically mentioned timeout errors or slow response times in their conversations.' 'What are the main issues and blockers in my current projects? Focus on technical challenges and timeline impacts.' 'Find insights about team collaboration and communication patterns from recent meetings and discussions.'
  - `rank_results` boolean — DEPRECATED: Use 'reranking_config' instead. Whether to enable additional ranking of search results. Default is false because results are already ranked when using an LLM for search (recommended approach). Only enable this if you're not using an LLM in your search pipeline and need additional result ranking. Migration: Replace 'rank_results: true' with 'reranking_config: {reranking_enabled: true, reranking_provider: "cohere", reranking_model: "rerank-v3.5"}'
  - `enable_agentic_graph` boolean — HIGHLY RECOMMENDED: Enable agentic graph search for intelligent, context-aware results. When enabled, the system can understand ambiguous references by first identifying specific entities from your memory graph, then performing targeted searches. Examples: 'customer feedback' → identifies your customers first, then finds their specific feedback; 'project issues' → identifies your projects first, then finds related issues; 'team meeting notes' → identifies team members first, then finds meeting notes. This provides much more relevant and comprehensive results. Set to false only if you need faster, simpler keyword-based search.
  - `external_user_id` string, nullable — Your application's user identifier to filter search results. This is the primary way to identify users. Use this for your app's user IDs (e.g., 'user_alice_123', UUID, email).
  - `user_id` string, nullable — DEPRECATED: Use 'external_user_id' instead. Internal Papr Parse user ID. Most developers should not use this field directly.
  - `organization_id` string, nullable — Optional organization ID for multi-tenant search scoping. When provided, search is scoped to memories within this organization.
  - `namespace_id` string, nullable — Optional namespace ID for multi-tenant search scoping. When provided, search is scoped to memories within this namespace.
  - `schema_id` string, nullable — Optional user-defined schema ID to use for this search. If provided, this schema (plus system schema) will be used for query generation. If not provided, system will automatically select relevant schema based on query content.
  - `metadata` MemoryMetadata — Metadata for memory request
    - `hierarchical_structures` union — Hierarchical structures to enable navigation from broad topics to specific ones
      - string
      - unknown[]
        - unknown
    - `createdAt` string, nullable — ISO datetime when the memory was created
    - `location` string, nullable
    - `topics` string[], nullable
    - `emoji tags` string[], nullable
    - `emotion tags` string[], nullable
    - `conversationId` string, nullable
    - `sourceUrl` string, nullable
    - `role` 'user' | 'assistant' — Role of the message sender
    - `category` 'preference' | 'task' | 'goal' | 'fact' | 'context' | 'skills' | 'learning', nullable — Memory category based on role. For users: preference, task, goal, fact, context. For assistants: skills, learning, task, goal, fact, context.
    - `user_id` string, nullable — DEPRECATED: Use 'external_user_id' at request level instead. This field will be removed in v2.
    - `external_user_id` string, nullable — DEPRECATED: Use 'external_user_id' at request level instead. This field will be removed in v2.
    - `external_user_read_access` string[], nullable — INTERNAL: Auto-populated for vector store filtering. Use memory_policy.acl instead.
    - `external_user_write_access` string[], nullable — INTERNAL: Auto-populated for vector store filtering. Use memory_policy.acl instead.
    - `user_read_access` string[], nullable — INTERNAL: Auto-populated for vector store filtering. Use memory_policy.acl instead.
    - `user_write_access` string[], nullable — INTERNAL: Auto-populated for vector store filtering. Use memory_policy.acl instead.
    - `workspace_read_access` string[], nullable — INTERNAL: Auto-populated for vector store filtering. Use memory_policy.acl instead.
    - `workspace_write_access` string[], nullable — INTERNAL: Auto-populated for vector store filtering. Use memory_policy.acl instead.
    - `role_read_access` string[], nullable — INTERNAL: Auto-populated for vector store filtering. Use memory_policy.acl instead.
    - `role_write_access` string[], nullable — INTERNAL: Auto-populated for vector store filtering. Use memory_policy.acl instead.
    - `namespace_read_access` string[], nullable — INTERNAL: Auto-populated for vector store filtering. Use memory_policy.acl instead.
    - `namespace_write_access` string[], nullable — INTERNAL: Auto-populated for vector store filtering. Use memory_policy.acl instead.
    - `organization_read_access` string[], nullable — INTERNAL: Auto-populated for vector store filtering. Use memory_policy.acl instead.
    - `organization_write_access` string[], nullable — INTERNAL: Auto-populated for vector store filtering. Use memory_policy.acl instead.
    - `pageId` string, nullable
    - `sourceType` string, nullable
    - `workspace_id` string, nullable
    - `upload_id` string, nullable — Upload ID for document processing workflows
    - `organization_id` string, nullable — DEPRECATED: Use 'organization_id' at request level instead. This field will be removed in v2.
    - `namespace_id` string, nullable — DEPRECATED: Use 'namespace_id' at request level instead. This field will be removed in v2.
    - `consent` string, nullable — DEPRECATED: Use 'memory_policy.consent' at request level instead. Values: 'explicit', 'implicit' (default), 'terms', 'none'.
    - `risk` string, nullable — DEPRECATED: Use 'memory_policy.risk' at request level instead. Values: 'none' (default), 'sensitive', 'flagged'.
    - `acl` object, nullable — DEPRECATED: Use 'memory_policy.acl' at request level instead. Format: {'read': [...], 'write': [...]}.
    - `sessionId` string, nullable
    - `post` string, nullable
    - `userMessage` string, nullable
    - `assistantMessage` string, nullable
    - `relatedGoals` string[], nullable
    - `relatedUseCases` string[], nullable
    - `relatedSteps` string[], nullable
    - `goalClassificationScores` number[], nullable
    - `useCaseClassificationScores` number[], nullable
    - `stepClassificationScores` number[], nullable
    - `customMetadata` object, nullable — Optional object for arbitrary custom metadata fields. Only string, number, boolean, or list of strings allowed. Nested dicts are not allowed.
  - `search_override` SearchOverrideSpecification — Complete search override specification provided by developer
    - `pattern` SearchOverridePattern, required — Developer-specified search pattern for search override
      - `source_label` string, required — Source node label (e.g., 'Memory', 'Person', 'Company'). Must match schema node types.
      - `relationship_type` string, required — Relationship type (e.g., 'ASSOCIATED_WITH', 'WORKS_FOR'). Must match schema relationship types.
      - `target_label` string, required — Target node label (e.g., 'Person', 'Company', 'Project'). Must match schema node types.
      - `direction` string — Relationship direction: '->' (outgoing), '<-' (incoming), or '-' (bidirectional)
    - `filters` SearchOverrideFilter[] — Property filters to apply to the search pattern
      - `node_type` string, required — Node type to filter (e.g., 'Person', 'Memory', 'Company')
      - `property_name` string, required — Property name to filter on (e.g., 'name', 'content', 'role')
      - `operator` string, required — Filter operator: 'CONTAINS', 'EQUALS', 'STARTS_WITH', 'IN'
      - `value` union, required — Filter value(s). Use list for 'IN' operator.
        - string
        - string[]
        - integer
        - number
        - boolean
    - `return_properties` string[], nullable — Specific properties to return. If not specified, returns all properties.
  - `reranking_config` RerankingConfig — Ranking provider for search results (cosine candidates → ranked list).
    - `reranking_enabled` boolean — When false, results stay in cosine order (same as provider=none).
    - `reranking_provider` 'none' | 'cohere' | 'openai' | 'papr_enhanced' | 'papr_max' — How to rank Qdrant cosine candidates after retrieval.
    - `reranking_model` string — Model for cohere/openai providers. Cohere: rerank-v3.5. OpenAI: gpt-5-nano, gpt-5-mini.
    - `domain_id` string, nullable — Signal domain for papr_enhanced / papr_max (default general).
    - `signal_thresholds` object, nullable — Min per-band scores for papr providers.
    - `return_signal_scores` boolean
    - `return_debug` boolean
    - `signal_multipliers` object, nullable
  - `policy` object, nullable — Policy for POST /v1/memory/search. External Cohere/OpenAI rerank and search-time ACL use top-level fields on SearchRequest (``reranking_config``, ``search_acl``) until wired here.
    - `consent` 'explicit' | 'implicit' | 'terms' | 'none' — How the data owner allowed this memory to be stored/used. Aligned with Open Memory Object (OMO) standard.
    - `risk` 'none' | 'sensitive' | 'flagged' — Post-ingest safety assessment of memory content. Aligned with Open Memory Object (OMO) standard.
    - `vector` VectorPolicy
      - `mode` 'fast' | 'enhanced' | 'max'
      - `domain_id` string, nullable
      - `signal_thresholds` object, nullable — Min per-band scores; maps to graph rerank signal_filters
      - `return_signal_scores` boolean
      - `return_debug` boolean
      - `signal_multipliers` object, nullable
    - `graph` GraphPolicyBlock
      - `mode` 'none' | 'auto' | 'manual'
      - `schema_id` string, nullable
      - `link_to` union — Shorthand DSL for node/edge constraints under policy.graph. Not a separate graph mode — expands into node_constraints and edge_constraints at resolve time and merges with any explicit constraints in the same request. Default create policy is upsert (create if not found); use dict form with create='lookup' for link-only. Prefer over deprecated top-level link_to.
        - string
        - string[]
        - object
      - `node_constraints` NodeConstraintInput[], nullable — Full node constraint objects. Same rules as policy.graph.link_to after expansion; use link_to for compact DSL or this field for explicit control. Both may be set.
        - `node_type` string, nullable — Node type this constraint applies to (e.g., 'Task', 'Project', 'Person'). Optional at schema level (implicit from parent UserNodeType), required at memory level (in memory_policy.node_constraints).
        - `when` object, nullable — Condition for when this constraint applies. Supports logical operators: '_and', '_or', '_not'. Examples: Simple: {'priority': 'high'} - matches when priority equals 'high'. AND: {'_and': [{'priority': 'high'}, {'status': 'active'}]} - all must match. OR: {'_or': [{'status': 'active'}, {'status': 'pending'}]} - any must match. NOT: {'_not': {'status': 'completed'}} - negation. Complex: {'_and': [{'priority': 'high'}, {'_or': [{'status': 'active'}, {'urgent': true}]}]}
        - `create` 'upsert' | 'lookup' | 'auto' | 'never' — 'upsert': Create if not found via search (default). 'lookup': Only link to existing nodes (controlled vocabulary). Deprecated aliases: 'auto' -> 'upsert', 'never' -> 'lookup'.
        - `on_miss` 'create' | 'ignore' | 'error', nullable — Explicit behavior when no match found via search. 'create': create new node (same as upsert). 'ignore': skip node creation (same as lookup). 'error': raise error if node not found. If specified, overrides 'create' field.
        - `link_only` boolean — DEPRECATED: Use create='lookup' instead. Shorthand for create='lookup'. When True, only links to existing nodes (controlled vocabulary). Equivalent to @lookup decorator in schema definitions.
        - `search` SearchConfigInput — Configuration for finding/selecting existing nodes. Defines which properties to match on and how, in priority order. The first matching property wins. **String Shorthand** (simple cases - converts to exact match): SearchConfig(properties=["id", "email"]) # Equivalent to: SearchConfig(properties=[PropertyMatch.exact("id"), PropertyMatch.exact("email")]) **Mixed Form** (combine strings and PropertyMatch): SearchConfig(properties=[ "id", # String -> exact match PropertyMatch.semantic("title", 0.9) # Full control ]) **Full Form** (maximum control): SearchConfig(properties=[ PropertyMatch(name="id", mode="exact"), PropertyMatch(name="title", mode="semantic", threshold=0.85) ]) **To select a specific node by ID**: SearchConfig(properties=[PropertyMatch.exact("id", "TASK-123")])
          - `properties` PropertyMatch[], nullable — Properties to match on, in priority order (first match wins). Accepts strings (converted to exact match) or PropertyMatch objects. Use PropertyMatch with 'value' field for specific node selection.
            - `name` string, required — Property name to match on (e.g., 'id', 'email', 'title')
            - `mode` 'semantic' | 'exact' | 'fuzzy' — Search mode for finding existing nodes.
            - `threshold` number — Similarity threshold for semantic/fuzzy modes (0.0-1.0). Ignored for exact mode.
            - `value` unknown
          - `via_relationship` RelationshipMatchInput[], nullable — Search for nodes via their relationships. Example: Find tasks assigned to a specific person. Each RelationshipMatch specifies edge_type, target_type, and target_search. Multiple relationship matches are ANDed together.
            - `edge_type` string, required — The relationship type to traverse (e.g., 'ASSIGNED_TO', 'BELONGS_TO')
            - `target_type` string, required — The target node type at the end of the relationship (e.g., 'Person', 'Project')
            - `target_search` SearchConfigInput, required — recursive
            - `direction` 'outgoing' | 'incoming' — Direction of the relationship from the node being searched. 'outgoing': node --edge--> target (default). 'incoming': target --edge--> node.
          - `mode` 'semantic' | 'exact' | 'fuzzy' — Search mode for finding existing nodes.
          - `threshold` number — Default similarity threshold for semantic/fuzzy matching (0.0-1.0). Used when property doesn't specify its own threshold.
        - `set` object, nullable — Set property values on nodes. Supports: 1. Exact value: {'status': 'done'} - sets exact value. 2. Auto-extract: {'status': {'mode': 'auto'}} - LLM extracts from content. 3. Text mode: {'summary': {'mode': 'auto', 'text_mode': 'merge'}} - controls text updates. For text properties, text_mode can be 'replace', 'append', or 'merge'.
      - `edge_constraints` EdgeConstraintInput[], nullable — Full edge constraint objects. Same rules as edge entries in policy.graph.link_to after expansion; both may be set in the same request.
        - `edge_type` string, nullable — Edge/relationship type this constraint applies to (e.g., 'MITIGATES', 'ASSIGNED_TO'). Optional at schema level (implicit from parent UserRelationshipType), required at memory level (in memory_policy.edge_constraints).
        - `source_type` string, nullable — Filter: only apply when source node is of this type. Example: source_type='SecurityBehavior' - only applies to edges from SecurityBehavior nodes.
        - `target_type` string, nullable — Filter: only apply when target node is of this type. Example: target_type='TacticDef' - only applies to edges targeting TacticDef nodes.
        - `direction` 'outgoing' | 'incoming' | 'both' — Direction of edges this constraint applies to. 'outgoing': edges where current node is source (default). 'incoming': edges where current node is target. 'both': applies in either direction.
        - `when` object, nullable — Condition for when this constraint applies. Supports logical operators: '_and', '_or', '_not'. Applied to edge properties or context. Example: {'_and': [{'severity': 'high'}, {'_not': {'status': 'deprecated'}}]}
        - `create` 'upsert' | 'lookup' | 'auto' | 'never' — 'upsert': Create target node if not found via search (default). 'lookup': Only link to existing target nodes (controlled vocabulary). When 'lookup', edges to non-existing targets are skipped. Deprecated aliases: 'auto' -> 'upsert', 'never' -> 'lookup'.
        - `on_miss` 'create' | 'ignore' | 'error', nullable — Explicit behavior when no target match found via search. 'create': create new target node (same as upsert). 'ignore': skip edge creation (same as lookup). 'error': raise error if target not found. If specified, overrides 'create' field.
        - `link_only` boolean — DEPRECATED: Use create='lookup' instead. Shorthand for create='lookup'. When True, only links to existing target nodes. Equivalent to @lookup decorator in schema definitions.
        - `search` SearchConfigInput — Configuration for finding/selecting existing nodes. Defines which properties to match on and how, in priority order. The first matching property wins. **String Shorthand** (simple cases - converts to exact match): SearchConfig(properties=["id", "email"]) # Equivalent to: SearchConfig(properties=[PropertyMatch.exact("id"), PropertyMatch.exact("email")]) **Mixed Form** (combine strings and PropertyMatch): SearchConfig(properties=[ "id", # String -> exact match PropertyMatch.semantic("title", 0.9) # Full control ]) **Full Form** (maximum control): SearchConfig(properties=[ PropertyMatch(name="id", mode="exact"), PropertyMatch(name="title", mode="semantic", threshold=0.85) ]) **To select a specific node by ID**: SearchConfig(properties=[PropertyMatch.exact("id", "TASK-123")])
          - `properties` PropertyMatch[], nullable — Properties to match on, in priority order (first match wins). Accepts strings (converted to exact match) or PropertyMatch objects. Use PropertyMatch with 'value' field for specific node selection.
            - `name` string, required — Property name to match on (e.g., 'id', 'email', 'title')
            - `mode` 'semantic' | 'exact' | 'fuzzy' — Search mode for finding existing nodes.
            - `threshold` number — Similarity threshold for semantic/fuzzy modes (0.0-1.0). Ignored for exact mode.
            - `value` unknown
          - `via_relationship` RelationshipMatchInput[], nullable — Search for nodes via their relationships. Example: Find tasks assigned to a specific person. Each RelationshipMatch specifies edge_type, target_type, and target_search. Multiple relationship matches are ANDed together.
            - `edge_type` string, required — The relationship type to traverse (e.g., 'ASSIGNED_TO', 'BELONGS_TO')
            - `target_type` string, required — The target node type at the end of the relationship (e.g., 'Person', 'Project')
            - `target_search` SearchConfigInput, required — recursive
            - `direction` 'outgoing' | 'incoming' — Direction of the relationship from the node being searched. 'outgoing': node --edge--> target (default). 'incoming': target --edge--> node.
          - `mode` 'semantic' | 'exact' | 'fuzzy' — Search mode for finding existing nodes.
          - `threshold` number — Default similarity threshold for semantic/fuzzy matching (0.0-1.0). Used when property doesn't specify its own threshold.
        - `set` object, nullable — Set property values on edges. Supports: 1. Exact value: {'weight': 1.0} - sets exact value. 2. Auto-extract: {'reason': {'mode': 'auto'}} - LLM extracts from content. Edge properties are useful for relationship metadata (weight, timestamp, reason, etc.).
      - `nodes` NodeSpec[], nullable
        - `id` string, required — Unique identifier for this node
        - `type` string, required — Node type/label (e.g., 'Transaction', 'Product', 'Person')
        - `properties` object — Properties for this node
      - `relationships` RelationshipSpec[], nullable
        - `source` string, required — ID of the source node
        - `target` string, required — ID of the target node
        - `type` string, required — Relationship type (e.g., 'PURCHASED', 'WORKS_AT', 'ASSIGNED_TO')
        - `properties` object, nullable — Optional properties for this relationship
  - `holographic_config` object, nullable — Configuration for holographic neural embedding transforms and H-COND scoring. Neural holographic embeddings use 13 brain-inspired frequency bands to encode hierarchical semantic metadata alongside the base embedding. H-COND (Holographic CONDitional) scoring uses phase alignment for improved relevance ranking.
    - `enabled` boolean — Whether to enable holographic embedding transforms
    - `search_mode` 'disabled' | 'integrated' | 'post_search' — Search modes for holographic neural embeddings
    - `hcond_boost_threshold` number — Phase alignment threshold above which to apply boost (0.0-1.0)
    - `hcond_boost_factor` number — Maximum boost to add for high alignment (0.0-0.5)
    - `hcond_penalty_factor` number — Maximum penalty for low alignment (0.0-0.5)
    - `frequency_schema_id` string, nullable — Frequency schema for holographic scoring. Use full ID (e.g. 'code_search:cosqa:2.0.0') or shorthand (e.g. 'cosqa'). Call GET /v1/frequencies to see available schemas and shortcuts.
    - `scoring_method` string, nullable — Scoring method for holographic search results. Default: 'egr_rerank' (highest accuracy, requires GPU). Options include: baseline, caesar8, egr_rerank, and 160+ others. If null, uses the schema's default_scoring_method.
    - `include_frequency_scores` boolean — If true, each result includes a per-frequency score breakdown showing how well the query matched the document on each dimension (e.g., programming_domain: 0.95, primary_operation: 0.72). Useful for understanding WHY a result ranked high or low.
    - `frequency_filters` object, nullable — Filter results by minimum alignment on specific frequency dimensions. Keys are field names (e.g., 'programming_domain', 'primary_operation'), values are minimum alignment scores (0.0-1.0). Example: {'programming_domain': 0.8, 'primary_operation': 0.7} Only returns results that match at least 80% on domain AND 70% on operation. Call GET /v1/frequencies to see available field names for each schema.
  - `omo_filter` OMOFilter — Filter for Open Memory Object (OMO) safety standards in search/retrieval. Use this to filter search results by consent level and/or risk level.
    - `min_consent` 'explicit' | 'implicit' | 'terms' | 'none' — How the data owner allowed this memory to be stored/used. Aligned with Open Memory Object (OMO) standard.
    - `exclude_consent` ConsentLevel[], nullable — Explicitly exclude memories with these consent levels. Example: exclude_consent=['none'] filters out all memories without consent.
    - `max_risk` 'none' | 'sensitive' | 'flagged' — Post-ingest safety assessment of memory content. Aligned with Open Memory Object (OMO) standard.
    - `exclude_risk` RiskLevel[], nullable — Explicitly exclude memories with these risk levels. Example: exclude_risk=['flagged'] filters out all flagged content.
    - `require_consent` boolean — If true, only return memories with explicit consent (consent != 'none'). Shorthand for exclude_consent=['none'].
    - `exclude_flagged` boolean — If true, exclude all flagged content (risk == 'flagged'). Shorthand for exclude_risk=['flagged'].
  - `search_acl` ACLConfig — Simplified Access Control List configuration. Aligned with Open Memory Object (OMO) standard. See: https://github.com/anthropics/open-memory-object **Supported Entity Prefixes:** | Prefix | Description | Validation | |--------|-------------|------------| | `user:` | Internal Papr user ID | Validated against Parse users | | `external_user:` | Your app's user ID | Not validated (your responsibility) | | `organization:` | Organization ID | Validated against your organizations | | `namespace:` | Namespace ID | Validated against your namespaces | | `workspace:` | Workspace ID | Validated against your workspaces | | `role:` | Parse role ID | Validated against your roles | **Examples:** ```python acl = ACLConfig( read=["external_user:alice_123", "organization:org_acme"], write=["external_user:alice_123"] ) ``` **Validation Rules:** - Internal entities (user, organization, namespace, workspace, role) are validated - External entities (external_user) are NOT validated - your app is responsible - Invalid internal entities will return an error - Unprefixed values default to `external_user:` for backwards compatibility
    - `read` string[] — Entity IDs that can read this memory. Format: 'prefix:id' (e.g., 'external_user:alice', 'organization:org_123'). Supported prefixes: user, external_user, organization, namespace, workspace, role. Unprefixed values treated as external_user for backwards compatibility.
    - `write` string[] — Entity IDs that can write/modify this memory. Format: 'prefix:id' (e.g., 'external_user:alice'). Supported prefixes: user, external_user, organization, namespace, workspace, role.

## Response `200`

Successfully retrieved memories

- SearchResponse
  - `code` integer — HTTP status code
  - `status` string — 'success' or 'error'
  - `data` SearchResult — Return type for SearchResult
    - `memories` Memory[], required
      - `id` string, required
      - `content` string, required
      - `title` string, nullable
      - `type` string, required
      - `metadata` union
        - string
        - object
      - `external_user_id` string, nullable
      - `customMetadata` object, nullable
      - `source_type` string
      - `context` ContextItem[], nullable
        - `role` 'user' | 'assistant', required
        - `content` string, required
      - `location` string, nullable
      - `tags` string[]
      - `hierarchical_structures` string
      - `source_url` string
      - `conversation_id` string
      - `topics` string[]
      - `steps` string[]
      - `current_step` string, nullable
      - `role` string, nullable — Role that generated this memory (user or assistant)
      - `category` string, nullable — Memory category based on role
      - `createdAt` string, date-time, nullable
      - `updatedAt` string, date-time, nullable
      - `acl` object, required
      - `user_id` string, required
      - `workspace_id` string, nullable
      - `organization_id` string, nullable — Organization ID that owns this memory
      - `namespace_id` string, nullable — Namespace ID this memory belongs to
      - `source_document_id` string, nullable
      - `source_message_id` string, nullable
      - `page_number` integer, nullable
      - `total_pages` integer, nullable
      - `file_url` string, nullable
      - `filename` string, nullable
      - `page` string, nullable
      - `external_user_read_access` string[], nullable
      - `external_user_write_access` string[], nullable
      - `user_read_access` string[], nullable
      - `user_write_access` string[], nullable
      - `workspace_read_access` string[], nullable
      - `workspace_write_access` string[], nullable
      - `role_read_access` string[], nullable
      - `role_write_access` string[], nullable
      - `namespace_read_access` string[], nullable
      - `namespace_write_access` string[], nullable
      - `organization_read_access` string[], nullable
      - `organization_write_access` string[], nullable
      - `embedding` number[], nullable — Full precision (float32) embedding vector from Qdrant. Typically 2560 dimensions for Qwen4B. Used for CoreML/ANE fp16 models.
      - `embedding_int8` integer[], nullable — Quantized INT8 embedding vector (values -128 to 127). 4x smaller than float32. Default format for efficiency.
      - `similarity_score` number, nullable — Cosine similarity from vector search (0-1). Measures semantic relevance to query.
      - `popularity_score` number, nullable — Popularity signal (0-1): 0.5*cacheConfidenceWeighted30d + 0.5*citationConfidenceWeighted30d. Uses stored EMA fields.
      - `recency_score` number, nullable — Recency signal (0-1): exp(-0.05 * days_since_last_access). Half-life ~14 days.
      - `reranker_score` number, nullable — Reranker relevance (0-1). From cross-encoder (Cohere/Qwen3/BGE) or LLM (GPT-5-nano).
      - `reranker_confidence` number, nullable — Reranker confidence (0-1). Meaningful for LLM reranking; equals reranker_score for cross-encoders.
      - `reranker_type` string, nullable — Reranker type: 'cross_encoder' (Cohere/Qwen3/BGE) or 'llm' (GPT-5-nano/GPT-4o-mini).
      - `relevance_score` number, nullable — Final relevance (0-1). rank_results=False: 0.6*sim + 0.25*pop + 0.15*recency. rank_results=True: RRF-based fusion.
      - `holographic_frequency_scores` object, nullable — Per-frequency-field scores from holographic scoring (e.g. {category: 0.9, topic: 0.7}). Only present when include_frequency_scores=True.
      - `metrics` object, nullable
      - `totalProcessingCost` number, nullable
    - `nodes` Node[], required
      - `label` string, required — Node type label - can be system type (Memory, Person, etc.) or custom type from UserGraphSchema
      - `properties` object, required — Node properties - structure depends on node type and schema
      - `schema_id` string, nullable — Reference to UserGraphSchema ID for custom nodes. Use GET /v1/schemas/{schema_id} to get full schema definition. Null for system nodes.
    - `schemas_used` string[], nullable — List of UserGraphSchema IDs used in this response. Use GET /v1/schemas/{id} to get full schema definitions.
  - `error` string, nullable — Error message if failed
  - `details` unknown
  - `search_id` string, nullable — Unique identifier for this search query, maps to QueryLog objectId in Parse Server

## Other responses

- `400` — Bad request
- `401` — Unauthorized
- `403` — Rate limit exceeded
- `404` — No relevant items found
- `415` — Unsupported Media Type
- `422` — Validation Error
- `500` — Internal server error

---

[API](https://skmtc.net/papr-ai/apis/papr-memory-api.md) · [All operations](https://skmtc.net/papr-ai/apis/papr-memory-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/papr-ai/papr-memory-api/revisions/b553be9aad37/schema)
