Skip to content

REST Endpoints

HEBBS exposes a REST API on port 6381. All endpoints use JSON for request and response bodies. Base URL: http://localhost:6381 (or your deployed host).

All REST endpoints require an Authorization: Bearer <key> header when auth is enabled (the default). Use the API key printed by the server on first start:

Terminal window
export HEBBS_API_KEY="hb_..."
curl -s http://localhost:6381/v1/health/ready \
-H "Authorization: Bearer $HEBBS_API_KEY"

To disable auth for local development, start the server with HEBBS_AUTH_ENABLED=false.

MethodPathDescriptionRequest BodyResponse Body
GET/v1/memoriesList memories with pagination and filtersQuery params: entity_id, kind, cursor, limitListMemoriesResponse
POST/v1/memoriesStore a new memorycontent, importance, context, entity_idMemory
GET/v1/memories/:idRetrieve a memory by IDMemory
GET/v1/memories/:id/edgesGet all edges (outgoing and incoming) for a memoryEdgesResponse
POST/v1/memories/batchBulk-retrieve memories by IDsmemory_idsMemory[]
POST/v1/recallRetrieve memories by cue and strategiescue, strategies, top_k, entity_id, scoring_weights, cue_context, ef_search, time_range, seed_memory_id, max_depth, edge_types, analogical_alphaRecallResponse
POST/v1/primePre-load session contextentity_id, max_memories, similarity_cue, scoring_weightsPrimeResponse
PUT/v1/revise/:idRevise an existing memorycontent, importance, context, context_mode, entity_idMemory
POST/v1/forgetDelete memories by criteriamemory_ids, entity_id, staleness_threshold_us, memory_kindForgetResponse
POST/v1/subscribeOpen SSE subscription streamentity_id, confidence_thresholdSSE event stream
POST/v1/subscribe/:id/feedFeed text to a subscriptiontext{}
DELETE/v1/subscribe/:idClose a subscription{}
GET/v1/insightsQuery consolidated insightsQuery params: entity_id, min_confidence, max_resultsMemory[]
POST/v1/graphQuery a subgraph around a center nodecenter_id, depth, edge_types, max_nodesGraphResponse
GET/v1/entitiesList all entity IDsstring[]
POST/v1/contradictions/prepareDeprecated. Get pending contradiction candidatesPendingContradiction[]
POST/v1/contradictions/commitDeprecated. Commit agent-reviewed verdictsverdictsContradictionCommitResponse
GET/v1/auth/whoamiReturns identity and workspace context of the authenticated keyWhoamiResponse
GET/v1/health/liveLiveness probe{"status": "alive"}
GET/v1/health/readyReadiness probe{"status": "ready"}
GET/v1/metricsPrometheus metricsText exposition format

All data-plane endpoints (memories, recall, prime, forget, upload, entities, insights) can be scoped to a specific workspace by prefixing the path with /v1/workspaces/<slug>/:

POST /v1/workspaces/sales-team/recall (instead of POST /v1/recall)
POST /v1/workspaces/enterprise-legal/memories
GET /v1/workspaces/sales-team/entities

Admin keys can target any workspace. Workspace-scoped keys can only access their bound workspace. The CLI --workspace flag handles this automatically.

REST endpoints derive the tenant from the Authorization header. The auth middleware resolves the API key to a tenant and scopes all operations to that tenant’s data. There is no tenant_id field in REST request bodies — tenant context comes exclusively from the auth layer.

When auth is disabled (HEBBS_AUTH_ENABLED=false), all REST requests operate on the default tenant.

Terminal window
curl -s -X POST http://localhost:6381/v1/memories \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $HEBBS_API_KEY" \
-d '{"content": "Met with the Acme Corp team about Q2 roadmap.", "importance": 0.8}' | jq .
Terminal window
curl -s -X POST http://localhost:6381/v1/recall \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $HEBBS_API_KEY" \
-d '{"cue": "Acme meeting", "strategies": ["similarity"]}' | jq .

Response includes score (composite), relevance (raw cosine similarity), and strategy_details:

[
{
"memory": { "memory_id": "...", "content": "Met with the Acme Corp team about Q2 roadmap.", "importance": 0.8, "kind": "episode", "..." : "..." },
"score": 0.6701,
"relevance": 0.8502,
"strategy_details": [{ "strategy": "similarity", "relevance": 0.8502, "distance": 0.1498 }]
}
]
Terminal window
curl -s -X POST http://localhost:6381/v1/recall \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $HEBBS_API_KEY" \
-d '{
"cue": "Acme meeting",
"strategies": ["similarity"],
"scoring_weights": {"w_relevance": 1.0, "w_recency": 0.0, "w_importance": 0.0, "w_reinforcement": 0.0}
}' | jq .

With these weights, score and relevance will be equal. See Composite Scoring for all weight options.

Terminal window
curl -s -X POST http://localhost:6381/v1/prime \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $HEBBS_API_KEY" \
-d '{"entity_id": "customer-42", "similarity_cue": "account history"}' | jq .
Terminal window
curl -s http://localhost:6381/v1/memories/01KK3S0KXYE22EFF489YRTH559 \
-H "Authorization: Bearer $HEBBS_API_KEY" | jq .
Terminal window
curl -s -X PUT http://localhost:6381/v1/revise/01KK3S0KXYE22EFF489YRTH559 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $HEBBS_API_KEY" \
-d '{"content": "Updated meeting notes with budget approval.", "importance": 0.9}' | jq .
Terminal window
curl -s -X POST http://localhost:6381/v1/forget \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $HEBBS_API_KEY" \
-d '{"entity_id": "customer-42"}' | jq .
Terminal window
curl -s "http://localhost:6381/v1/insights?entity_id=customer-42&max_results=5" \
-H "Authorization: Bearer $HEBBS_API_KEY" | jq .

Open a subscription stream:

Terminal window
curl -s -N -X POST http://localhost:6381/v1/subscribe \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $HEBBS_API_KEY" \
-d '{"entity_id": "customer-42", "confidence_threshold": 0.6}'

Feed text (in a second terminal):

Terminal window
curl -s -X POST http://localhost:6381/v1/subscribe/1/feed \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $HEBBS_API_KEY" \
-d '{"text": "Customer asked about dark mode preferences."}'

Close the subscription:

Terminal window
curl -s -X DELETE http://localhost:6381/v1/subscribe/1 \
-H "Authorization: Bearer $HEBBS_API_KEY"

Browse memories with cursor-based pagination and optional filters.

Terminal window
# List first 50 memories
curl -s "http://localhost:6381/v1/memories?limit=50" \
-H "Authorization: Bearer $HEBBS_API_KEY" | jq .
# Filter by entity and kind
curl -s "http://localhost:6381/v1/memories?entity_id=customer-42&kind=episode&limit=20" \
-H "Authorization: Bearer $HEBBS_API_KEY" | jq .
# Paginate using cursor from previous response
curl -s "http://localhost:6381/v1/memories?cursor=01KK3S0KXYE22EFF489YRTH559&limit=20" \
-H "Authorization: Bearer $HEBBS_API_KEY" | jq .

Query parameters:

FieldTypeRequiredDefaultDescription
entity_idstringNoFilter to a specific entity
kindstringNoFilter by memory kind: episode, insight, revision, document, proposition
cursorstringNoHex memory ID; returns memories after this ID (for pagination)
limitintegerNo100Max memories to return (capped at 1000)

Response:

{
"memories": [
{ "memory_id": "...", "content": "...", "importance": 0.8, "kind": "episode", "..." : "..." }
],
"next_cursor": "01KK3S0KXYE22EFF489YRTH559"
}

next_cursor is null when there are no more results. Pass it as the cursor query parameter to fetch the next page.

Get all outgoing and incoming graph edges for a memory.

Terminal window
curl -s http://localhost:6381/v1/memories/01KK3S0KXYE22EFF489YRTH559/edges \
-H "Authorization: Bearer $HEBBS_API_KEY" | jq .

Response:

{
"outgoing": [
{
"source_id": "01KK3S0KXYE22EFF489YRTH559",
"target_id": "01KK3T1MBYE33FGG590ZSUI660",
"edge_type": "caused_by",
"confidence": 0.95,
"timestamp_us": 1720000000000000
}
],
"incoming": [
{
"source_id": "01KK3T1MBYE33FGG590ZSUI660",
"target_id": "01KK3S0KXYE22EFF489YRTH559",
"edge_type": "insight_from",
"confidence": 0.88,
"timestamp_us": 1720000100000000
}
]
}

Edge types: caused_by, related_to, followed_by, revised_from, insight_from, contradicts, has_entity, entity_relation, proposition_of.

Retrieve multiple memories in a single request.

Terminal window
curl -s -X POST http://localhost:6381/v1/memories/batch \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $HEBBS_API_KEY" \
-d '{"memory_ids": ["01KK3S0KXYE22EFF489YRTH559", "01KK3T1MBYE33FGG590ZSUI660"]}' | jq .

Request body:

FieldTypeRequiredDescription
memory_idsstring[]YesHex-encoded memory IDs (max 500)

Response: Array of Memory objects. Missing IDs are silently skipped.

Query a subgraph centered on a memory node. Returns all nodes and edges within the specified traversal depth.

Terminal window
curl -s -X POST http://localhost:6381/v1/graph \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $HEBBS_API_KEY" \
-d '{
"center_id": "01KK3S0KXYE22EFF489YRTH559",
"depth": 2,
"max_nodes": 100
}' | jq .

Request body:

FieldTypeRequiredDefaultDescription
center_idstringYesHex memory ID of the center node
depthintegerNo2Maximum traversal depth from center (capped at 5)
edge_typesstring[]Noall typesEdge types to traverse (e.g. ["caused_by", "related_to"])
max_nodesintegerNo100Maximum nodes to return (capped at 500)

Response:

{
"nodes": [
{ "memory_id": "...", "content": "...", "importance": 0.8, "kind": "episode", "..." : "..." }
],
"edges": [
{
"source_id": "01KK3S0KXYE22EFF489YRTH559",
"target_id": "01KK3T1MBYE33FGG590ZSUI660",
"edge_type": "caused_by",
"confidence": 0.95,
"timestamp_us": 1720000000000000
}
],
"truncated": false
}

truncated is true when the traversal hit max_nodes before exhausting all reachable nodes at the requested depth.

List all entity IDs that have at least one memory.

Terminal window
curl -s http://localhost:6381/v1/entities \
-H "Authorization: Bearer $HEBBS_API_KEY" | jq .

Response:

["customer-42", "agent-sales-01", "user-preferences"]

Prepare reflection data without calling any LLM. Returns clustered memories and prompts for agent-driven insight generation.

Terminal window
curl -s -X POST http://localhost:6381/v1/reflect/prepare \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $HEBBS_API_KEY" \
-d '{"entity_id": "customer-42"}' | jq .

Request body:

FieldTypeRequiredDescription
entity_idstringNoEntity scope (omit for global)
since_usintegerNoOnly include memories since this timestamp (microseconds)

Response:

{
"session_id": "01JQXYZ...",
"memories_processed": 47,
"clusters": [
{
"cluster_id": 0,
"member_count": 8,
"proposal_system_prompt": "...",
"proposal_user_prompt": "...",
"memory_ids": ["aabb1122...", "ccdd3344..."],
"validation_context": { ... },
"memories": [
{
"memory_id": "aabb1122...",
"content": "The user prefers dark mode in all applications",
"importance": 0.8,
"entity_id": "user_prefs",
"created_at": 1720000000000000
}
]
}
],
"existing_insight_count": 3
}

Commit agent-produced insights from a previous reflect/prepare call.

Terminal window
curl -s -X POST http://localhost:6381/v1/reflect/commit \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $HEBBS_API_KEY" \
-d '{
"session_id": "01JQXYZ...",
"insights": [
{
"content": "Customer consistently prefers dark mode across all applications",
"confidence": 0.9,
"source_memory_ids": ["aabb1122...", "ccdd3344..."],
"tags": ["preference", "ui"]
}
]
}' | jq .

Request body:

FieldTypeRequiredDescription
session_idstringYesSession ID from reflect/prepare
insightsarrayYesArray of insight objects
insights[].contentstringYesInsight text
insights[].confidencefloatYesConfidence score (0.0–1.0)
insights[].source_memory_idsstring[]YesHex-encoded memory IDs from the cluster
insights[].tagsstring[]NoCategorical labels
insights[].cluster_idintegerNoCluster ID from prepare output

Response:

{
"insights_created": 1
}

Sessions expire after 10 minutes. Source memory IDs must be from the original prepare output.

Retrieve pending contradiction candidates. In the previous architecture, these were flagged by a heuristic classifier and required external agent review. HEBBS now resolves contradictions autonomously using its built-in LLM.

Terminal window
curl -s -X POST http://localhost:6381/v1/contradictions/prepare \
-H "Authorization: Bearer $HEBBS_API_KEY" | jq .

Response:

[
{
"pending_id": "abc123def456...",
"memory_id_a": "aabb1122...",
"memory_id_b": "ccdd3344...",
"content_a_snippet": "The system is reliable and stable",
"content_b_snippet": "The system is unreliable and unstable",
"classifier_score": 0.65,
"classifier_method": "heuristic",
"similarity": 0.82,
"created_at": 1720000000000000
}
]

Returns an empty array when no pending candidates exist.

Commit verdicts for pending contradiction candidates after agent review.

Terminal window
curl -s -X POST http://localhost:6381/v1/contradictions/commit \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $HEBBS_API_KEY" \
-d '{
"verdicts": [
{"pending_id": "abc123def456...", "verdict": "contradiction", "confidence": 0.9, "reasoning": "Direct conflict in reliability assessment"},
{"pending_id": "def789...", "verdict": "dismiss", "confidence": 0.95, "reasoning": "Different topics"}
]
}' | jq .

Request body:

FieldTypeRequiredDescription
verdictsarrayYesArray of verdict objects
verdicts[].pending_idstringYesPending candidate ID from prepare
verdicts[].verdictstringYes"contradiction", "revision", or "dismiss"
verdicts[].confidencefloatYesAgent confidence (0.0—1.0)
verdicts[].reasoningstringNoExplanation for the verdict

Response:

{
"contradictions_confirmed": 1,
"revisions_created": 0,
"dismissed": 1
}

See Contradiction Detection for the full two-phase pipeline explanation.

  • subscribe uses Server-Sent Events (SSE) over REST for real-time pushes. Full bidirectional streaming is available via gRPC.
  • All /v1/* endpoints return JSON. Use Content-Type: application/json for request bodies.
  • Memory IDs in REST paths are 32-character hex strings (16 bytes).