GoodMemGoodMem
ReferenceAPIREST APIMemories

Advanced semantic memory retrieval with JSON

POST /v1/memories:retrieve: Streams semantic retrieval results with full feature support including context items and embedder weight overrides, per-space filters, and request-level HNSW tuning.

POST
/v1/memories:retrieve

Streams semantic retrieval results with full feature support including context items and embedder weight overrides, per-space filters, and request-level HNSW tuning. Supports SSE (text/event-stream) and NDJSON (application/x-ndjson) formats.

AUTHORIZATION: Every requested space must grant LIST_MEMORY on that exact space and READ_MEMORY through DIRECT_MEMBERS_OF the space before retrieval begins.

Authorization

ApiKeyAuth
headerx-api-key<token>

Header Parameters

Accept?string

Response format: 'text/event-stream' for Server-Sent Events or 'application/x-ndjson' for newline-delimited JSON

Value in"text/event-stream""application/x-ndjson"
GoodMem-Timeout-Ms?integer

Optional waiting budget in milliseconds, measured from REST servlet ingress and shared across all internal gRPC calls. Supply one decimal integer from 1 to 86400000. Omission adds no deadline. Existing shorter deadlines still apply. Expiry returns HTTP 504 before streaming starts; after streaming starts, no successful completion event is sent. Use SSE or opt into GoodMem-Stream-Terminal for an explicit terminal outcome. Retrieval work is cooperatively cancelled. An accepted mutation may still commit after timeout or disconnect; a failed response does not imply rollback.

Formatint64
Range1 <= value <= 86400000
GoodMem-Stream-Terminal?"true"

Set true to receive a final NDJSON transport record. The response echoes this header when enabled. Require a completed record to establish stream success; EOF alone and a result-set END do not establish success. SSE uses close on success and error on failure.

Value in"true"

Request Body

Request body with query, context, and space configurations

application/json
  1. body

Request body for semantic memory retrieval with optional embedder weight overrides.

message*string

Primary query/message for semantic search.

Length1 <= length <= 10000
Example"How do I implement vector search?"
context?array<|>|

Optional context items (text or binary) to provide additional context for the search.

Example
[  {    "text": "Focus on implementation details"  },  {    "binary": {      "contentType": "image/png",      "data": "base64data..."    }  }]
spaceKeys*array<>

List of spaces to search with optional per-embedder weight overrides.

Example
[  {    "spaceId": "550e8400-e29b-41d4-a716-446655440000",    "embedderWeights": [      {        "embedderId": "550e8400-e29b-41d4-a716-446655440001",        "weight": 1.5      }    ],    "filter": "lower(CAST(val('$.primaryLocation.city') AS TEXT)) = 'manila'"  }]
requestedSize?|

Maximum number of memories to retrieve. Zero or omitted uses 20; negative values are invalid.

Formatint32
Range0 <= value
Default20
outputBudget?|

Optional soft cap for generated retrieve replies. When set to a positive token count, chat post-processing uses this value as the LLM completion-token budget.

Example
{  "tokens": 512}
fetchMemory?|

Whether to include streamed memory-definition records in the response. Defaults to true when omitted. These records include memory metadata and audit fields, but omit originalContent unless fetchMemoryContent is true.

Defaulttrue
fetchMemoryContent?|

Whether streamed memory-definition records include originalContent bytes. Requires fetchMemory=true. Defaults to false when omitted.

Defaultfalse
hnsw?|

Optional request-level HNSW tuning overrides. Advanced usage; available on POST retrieve.

Example
{  "efSearch": 200,  "iterativeScan": "ITERATIVE_SCAN_RELAXED_ORDER",  "maxScanTuples": 20000,  "scanMemMultiplier": 2.5}
postProcessor?|

Optional post-processor configuration to transform retrieval results. See ChatPostProcessor reference for the built-in ChatPostProcessor parameters.

Example
{  "name": "com.goodmem.retrieval.postprocess.ChatPostProcessorFactory",  "config": {    "reranker_id": "a1b2c3d4-e5f6-7890-1234-567890abcdef",    "relevance_threshold": 0.7,    "chronological_resort": true,    "llm_id": "72eaec11-c698-4262-970b-83aa957f9e02",    "llm_temp": 0.3,    "max_results": 10,    "sys_prompt": "You are an AI assistant helping to synthesize retrieved memory content.",    "prompt": "User Query: \"{{ userQuery }}\"\n\nRetrieved Data:\n{{ dataSection }}",    "gen_token_budget": 512  }}
logging?|

Optional durable request logging block for POST retrieve requests. Set logging.enabled=true to opt in, or supply flat scalar logging.callerAttributes to attach if caller opt-in or an admin policy logs the request.

Example
{  "enabled": false}

Response Body

Successfully started streaming retrieval results

  1. response

Streaming event from memory retrieval operation

resultSetBoundary?|

Result set boundary marker (BEGIN/END)

Example
{  "resultSetId": "550e8400-e29b-41d4-a716-446655440000",  "kind": "BEGIN",  "stageName": "retrieve",  "expectedItems": 10}
abstractReply?|

Generated abstractive reply

Example
{  "text": "Based on the retrieved memories, the recommended approach is to use vector similarity search combined with keyword filtering for optimal results.",  "relevanceScore": 0.85,  "resultSetId": "550e8400-e29b-41d4-a716-446655440000"}
retrievedItem?||

A retrieved memory or chunk

Example
{  "memory": {    "memoryId": "550e8400-e29b-41d4-a716-446655440000",    "spaceId": "550e8400-e29b-41d4-a716-446655440001",    "originalContent": "VGhpcyBpcyBiYXNlNjQgYmluYXJ5Lg==",    "originalContentSha256": "9f2c8c5a9d740eb56d...",    "originalContentRef": "s3://my-bucket/document.pdf",    "contentType": "text/plain",    "processingStatus": "COMPLETED",    "pageImageStatus": "COMPLETED",    "pageImageCount": 12,    "createdAt": 1672531200000,    "updatedAt": 1672531200000,    "createdById": "550e8400-e29b-41d4-a716-446655440002",    "updatedById": "550e8400-e29b-41d4-a716-446655440002",    "chunkingConfig": {      "recursive": {        "chunkSize": 1000,        "chunkOverlap": 200,        "separators": [          "\n\n",          "\n",          ".",          " "        ],        "keepStrategy": "KEEP_END",        "separatorIsRegex": false,        "lengthMeasurement": "CHARACTER_COUNT"      },      "sentence": {        "maxChunkSize": 1000,        "minChunkSize": 100,        "enableLanguageDetection": true,        "lengthMeasurement": "CHARACTER_COUNT"      }    },    "processingHistory": {      "latestJob": {        "jobId": 42,        "jobType": "document_processor",        "status": "BACKGROUND_JOB_RUNNING",        "attempts": 1,        "maxAttempts": 5,        "runAt": 1714713600000,        "leaseUntil": 1714713660000,        "lockedBy": "worker-1",        "lastError": "Transient network failure",        "updatedAt": 1714713615000,        "failureStage": "DOCUMENT_PROCESSING_STAGE_GENERATING_EMBEDDINGS"      }    }  },  "chunk": {    "resultSetId": "550e8400-e29b-41d4-a716-446655440000",    "chunk": {      "chunkId": "550e8400-e29b-41d4-a716-446655440000",      "memoryId": "550e8400-e29b-41d4-a716-446655440001",      "chunkSequenceNumber": 1,      "chunkText": "This is a chunk of text from the memory content.",      "vectorStatus": "COMPLETED",      "startOffset": 0,      "endOffset": 150,      "createdAt": 1617293472000,      "updatedAt": 1617293472000,      "createdById": "550e8400-e29b-41d4-a716-446655440000",      "updatedById": "550e8400-e29b-41d4-a716-446655440000"    },    "memoryIndex": 2,    "relevanceScore": 0.92  }}
memoryDefinition?|

Memory object to add to client's memories array

Example
{  "memoryId": "550e8400-e29b-41d4-a716-446655440000",  "spaceId": "550e8400-e29b-41d4-a716-446655440001",  "originalContent": "VGhpcyBpcyBiYXNlNjQgYmluYXJ5Lg==",  "originalContentSha256": "9f2c8c5a9d740eb56d...",  "originalContentRef": "s3://my-bucket/document.pdf",  "contentType": "text/plain",  "processingStatus": "COMPLETED",  "pageImageStatus": "COMPLETED",  "pageImageCount": 12,  "createdAt": 1672531200000,  "updatedAt": 1672531200000,  "createdById": "550e8400-e29b-41d4-a716-446655440002",  "updatedById": "550e8400-e29b-41d4-a716-446655440002",  "chunkingConfig": {    "recursive": {      "chunkSize": 1000,      "chunkOverlap": 200,      "separators": [        "\n\n",        "\n",        ".",        " "      ],      "keepStrategy": "KEEP_END",      "separatorIsRegex": false,      "lengthMeasurement": "CHARACTER_COUNT"    },    "sentence": {      "maxChunkSize": 1000,      "minChunkSize": 100,      "enableLanguageDetection": true,      "lengthMeasurement": "CHARACTER_COUNT"    }  },  "processingHistory": {    "latestJob": {      "jobId": 42,      "jobType": "document_processor",      "status": "BACKGROUND_JOB_RUNNING",      "attempts": 1,      "maxAttempts": 5,      "runAt": 1714713600000,      "leaseUntil": 1714713660000,      "lockedBy": "worker-1",      "lastError": "Transient network failure",      "updatedAt": 1714713615000,      "failureStage": "DOCUMENT_PROCESSING_STAGE_GENERATING_EMBEDDINGS"    }  }}
status?|

Warning or non-fatal status with granular codes (operation continues)

Example
{  "code": "VECTOR_SEARCH_PARTIAL",  "message": "Some embedders were unavailable, returning partial results"}
Example Request
curl -X POST 'https://your-goodmem-server.example.com/v1/memories:retrieve' \  -H 'Accept: application/x-ndjson' \  -H 'GoodMem-Timeout-Ms: 30000' \  -H 'Content-Type: application/json' \  -d '{  "message": "How do I implement vector search?",  "context": [    {      "text": "Please focus on implementation details."    }  ],  "spaceKeys": [    {      "spaceId": "550e8400-e29b-41d4-a716-446655440000",      "embedderWeights": [        {          "embedderId": "550e8400-e29b-41d4-a716-446655440000",          "weight": 1.5        }      ],      "filter": "CAST(val('\''$.effectiveDate'\'') AS DATE) >= CAST('\''2024-10-01'\'' AS DATE)"    }  ],  "requestedSize": 10,  "outputBudget": {    "tokens": 512  },  "fetchMemory": true,  "fetchMemoryContent": false,  "hnsw": {    "efSearch": 200,    "iterativeScan": "ITERATIVE_SCAN_RELAXED_ORDER",    "maxScanTuples": 20000,    "scanMemMultiplier": 2.5  },  "postProcessor": {    "name": "com.goodmem.retrieval.postprocess.ChatPostProcessorFactory",    "config": {      "reranker_id": "a1b2c3d4-e5f6-7890-1234-567890abcdef",      "relevance_threshold": 0.7,      "chronological_resort": true,      "llm_id": "72eaec11-c698-4262-970b-83aa957f9e02",      "llm_temp": 0.3,      "max_results": 10,      "sys_prompt": "You are an AI assistant helping to synthesize retrieved memory content.",      "prompt": "User Query: \"{{ userQuery }}\"\n\nRetrieved Data:\n{{ dataSection }}",      "gen_token_budget": 512    }  },  "logging": {    "enabled": false  }}'
Example Response
{  "resultSetBoundary": {    "resultSetId": "550e8400-e29b-41d4-a716-446655440000",    "kind": "BEGIN",    "stageName": "retrieve",    "expectedItems": 10  },  "abstractReply": {    "text": "Based on the retrieved memories, the recommended approach is to use vector similarity search combined with keyword filtering for optimal results.",    "relevanceScore": 0.85,    "resultSetId": "550e8400-e29b-41d4-a716-446655440000"  },  "retrievedItem": {    "memory": {      "memoryId": "550e8400-e29b-41d4-a716-446655440000",      "spaceId": "550e8400-e29b-41d4-a716-446655440001",      "originalContent": "VGhpcyBpcyBiYXNlNjQgYmluYXJ5Lg==",      "originalContentSha256": "9f2c8c5a9d740eb56d...",      "originalContentRef": "s3://my-bucket/document.pdf",      "contentType": "text/plain",      "processingStatus": "COMPLETED",      "pageImageStatus": "COMPLETED",      "pageImageCount": 12,      "createdAt": 1672531200000,      "updatedAt": 1672531200000,      "createdById": "550e8400-e29b-41d4-a716-446655440002",      "updatedById": "550e8400-e29b-41d4-a716-446655440002",      "chunkingConfig": {        "recursive": {          "chunkSize": 1000,          "chunkOverlap": 200,          "separators": [            "\n\n",            "\n",            ".",            " "          ],          "keepStrategy": "KEEP_END",          "separatorIsRegex": false,          "lengthMeasurement": "CHARACTER_COUNT"        },        "sentence": {          "maxChunkSize": 1000,          "minChunkSize": 100,          "enableLanguageDetection": true,          "lengthMeasurement": "CHARACTER_COUNT"        }      },      "processingHistory": {        "latestJob": {          "jobId": 42,          "jobType": "document_processor",          "status": "BACKGROUND_JOB_RUNNING",          "attempts": 1,          "maxAttempts": 5,          "runAt": 1714713600000,          "leaseUntil": 1714713660000,          "lockedBy": "worker-1",          "lastError": "Transient network failure",          "updatedAt": 1714713615000,          "failureStage": "DOCUMENT_PROCESSING_STAGE_GENERATING_EMBEDDINGS"        }      }    },    "chunk": {      "resultSetId": "550e8400-e29b-41d4-a716-446655440000",      "chunk": {        "chunkId": "550e8400-e29b-41d4-a716-446655440000",        "memoryId": "550e8400-e29b-41d4-a716-446655440001",        "chunkSequenceNumber": 1,        "chunkText": "This is a chunk of text from the memory content.",        "vectorStatus": "COMPLETED",        "startOffset": 0,        "endOffset": 150,        "createdAt": 1617293472000,        "updatedAt": 1617293472000,        "createdById": "550e8400-e29b-41d4-a716-446655440000",        "updatedById": "550e8400-e29b-41d4-a716-446655440000"      },      "memoryIndex": 2,      "relevanceScore": 0.92    }  },  "memoryDefinition": {    "memoryId": "550e8400-e29b-41d4-a716-446655440000",    "spaceId": "550e8400-e29b-41d4-a716-446655440001",    "originalContent": "VGhpcyBpcyBiYXNlNjQgYmluYXJ5Lg==",    "originalContentSha256": "9f2c8c5a9d740eb56d...",    "originalContentRef": "s3://my-bucket/document.pdf",    "contentType": "text/plain",    "processingStatus": "COMPLETED",    "pageImageStatus": "COMPLETED",    "pageImageCount": 12,    "createdAt": 1672531200000,    "updatedAt": 1672531200000,    "createdById": "550e8400-e29b-41d4-a716-446655440002",    "updatedById": "550e8400-e29b-41d4-a716-446655440002",    "chunkingConfig": {      "recursive": {        "chunkSize": 1000,        "chunkOverlap": 200,        "separators": [          "\n\n",          "\n",          ".",          " "        ],        "keepStrategy": "KEEP_END",        "separatorIsRegex": false,        "lengthMeasurement": "CHARACTER_COUNT"      },      "sentence": {        "maxChunkSize": 1000,        "minChunkSize": 100,        "enableLanguageDetection": true,        "lengthMeasurement": "CHARACTER_COUNT"      }    },    "processingHistory": {      "latestJob": {        "jobId": 42,        "jobType": "document_processor",        "status": "BACKGROUND_JOB_RUNNING",        "attempts": 1,        "maxAttempts": 5,        "runAt": 1714713600000,        "leaseUntil": 1714713660000,        "lockedBy": "worker-1",        "lastError": "Transient network failure",        "updatedAt": 1714713615000,        "failureStage": "DOCUMENT_PROCESSING_STAGE_GENERATING_EMBEDDINGS"      }    }  },  "status": {    "code": "VECTOR_SEARCH_PARTIAL",    "message": "Some embedders were unavailable, returning partial results"  }}