GoodMemGoodMem
ReferenceAPIREST APIMemories

Stream semantic memory retrieval

GET /v1/memories:retrieve: Streams semantic retrieval results based on query and context.

GET
/v1/memories:retrieve

Streams semantic retrieval results based on query and context. Supports SSE (text/event-stream) and NDJSON (application/x-ndjson) formats. Advanced HNSW tuning options are available on POST /v1/memories:retrieve only. GET supports only a boolean logging toggle; caller attribute query parameters are rejected and must be sent via POST.

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>

Query Parameters

message*string

Primary query/message for semantic search

spaceIds?string

Comma-separated list of space UUIDs to search within. The snake_case alias space_ids is also accepted.

filter?string

Optional filter expression applied to every space ID supplied via the query parameter. Use the POST variant if you need distinct filters per space. See Filter Expressions reference for syntax and examples.

requestedSize?integer

Maximum number of memories to retrieve. Zero or omitted uses 20; negative values are invalid. The snake_case alias requested_size is also accepted.

Formatint32
fetchMemory?boolean

Whether to stream memory-definition records (defaults to true). These omit originalContent unless fetchMemoryContent=true. The snake_case alias fetch_memory is also accepted.

Defaulttrue
fetchMemoryContent?boolean

Whether streamed memory-definition records include originalContent bytes (defaults to false). Requires fetchMemory=true. The snake_case alias fetch_memory_content is also accepted.

Defaultfalse
postProcessorRerankerId?string

UUID of reranker to use for ChatPostProcessor (enables post-processing). Accepted aliases: ppRerankerId, pp_reranker_id.

postProcessorLlmId?string

UUID of LLM to use for ChatPostProcessor generation. Accepted aliases: ppLlmId, pp_llm_id.

postProcessorRelevanceThreshold?number

Minimum relevance score for ChatPostProcessor. If omitted, no relevance threshold is applied. Accepted aliases: ppRelevanceThreshold, pp_relevance_threshold.

Formatdouble
postProcessorLlmTemp?number

LLM temperature for ChatPostProcessor generation (default: 0.3). Accepted aliases: ppLlmTemp, pp_llm_temp.

Formatdouble
Default0.3
postProcessorMaxResults?integer

Maximum results for ChatPostProcessor. If omitted, the processor uses requestedSize when that value is positive; otherwise it falls back to 10. Accepted aliases: ppMaxResults, pp_max_results.

Formatint32
postProcessorChronologicalResort?boolean

Whether ChatPostProcessor should resort by creation time (default: false). Accepted aliases: ppChronologicalResort, pp_chronological_resort.

Defaultfalse
loggingEnabled?boolean

Boolean caller opt-in durable-request-logging toggle for GET retrieve only. Accepted alias: logging_enabled. Caller attributes are not supported on GET; use POST /v1/memories:retrieve with logging.callerAttributes.

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"

Response Body

Streaming memory retrieval results (supports both SSE and NDJSON formats)

  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 GET 'https://your-goodmem-server.example.com/v1/memories:retrieve?message=How+do+I+implement+vector+search%3F&spaceIds=550e8400-e29b-41d4-a716-446655440000%2C550e8400-e29b-41d4-a716-446655440001&filter=CAST%28val%28%27%24.effectiveDate%27%29+AS+DATE%29+%3E%3D+CAST%28%272024-10-01%27+AS+DATE%29&requestedSize=10&fetchMemory=true&fetchMemoryContent=false&postProcessorRerankerId=550e8400-e29b-41d4-a716-446655440000&postProcessorLlmId=550e8400-e29b-41d4-a716-446655440001&postProcessorRelevanceThreshold=0.5&postProcessorLlmTemp=0.3&postProcessorMaxResults=10&postProcessorChronologicalResort=false&loggingEnabled=true' \  -H 'Accept: application/x-ndjson' \  -H 'GoodMem-Timeout-Ms: 30000'
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"  }}