REST Endpoints
Overview
Section titled “Overview”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).
Authentication
Section titled “Authentication”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:
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.
Endpoint Reference
Section titled “Endpoint Reference”| Method | Path | Description | Request Body | Response Body |
|---|---|---|---|---|
| GET | /v1/memories | List memories with pagination and filters | Query params: entity_id, kind, cursor, limit | ListMemoriesResponse |
| POST | /v1/memories | Store a new memory | content, importance, context, entity_id | Memory |
| GET | /v1/memories/:id | Retrieve a memory by ID | — | Memory |
| GET | /v1/memories/:id/edges | Get all edges (outgoing and incoming) for a memory | — | EdgesResponse |
| POST | /v1/memories/batch | Bulk-retrieve memories by IDs | memory_ids | Memory[] |
| POST | /v1/recall | Retrieve memories by cue and strategies | cue, strategies, top_k, entity_id, scoring_weights, cue_context, ef_search, time_range, seed_memory_id, max_depth, edge_types, analogical_alpha | RecallResponse |
| POST | /v1/prime | Pre-load session context | entity_id, max_memories, similarity_cue, scoring_weights | PrimeResponse |
| PUT | /v1/revise/:id | Revise an existing memory | content, importance, context, context_mode, entity_id | Memory |
| POST | /v1/forget | Delete memories by criteria | memory_ids, entity_id, staleness_threshold_us, memory_kind | ForgetResponse |
| POST | /v1/subscribe | Open SSE subscription stream | entity_id, confidence_threshold | SSE event stream |
| POST | /v1/subscribe/:id/feed | Feed text to a subscription | text | {} |
| DELETE | /v1/subscribe/:id | Close a subscription | — | {} |
| GET | /v1/insights | Query consolidated insights | Query params: entity_id, min_confidence, max_results | Memory[] |
| POST | /v1/graph | Query a subgraph around a center node | center_id, depth, edge_types, max_nodes | GraphResponse |
| GET | /v1/entities | List all entity IDs | — | string[] |
| POST | /v1/contradictions/prepare | Deprecated. Get pending contradiction candidates | — | PendingContradiction[] |
| POST | /v1/contradictions/commit | Deprecated. Commit agent-reviewed verdicts | verdicts | ContradictionCommitResponse |
| GET | /v1/auth/whoami | Returns identity and workspace context of the authenticated key | — | WhoamiResponse |
| GET | /v1/health/live | Liveness probe | — | {"status": "alive"} |
| GET | /v1/health/ready | Readiness probe | — | {"status": "ready"} |
| GET | /v1/metrics | Prometheus metrics | — | Text exposition format |
Workspace-Scoped Routing
Section titled “Workspace-Scoped Routing”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/memoriesGET /v1/workspaces/sales-team/entitiesAdmin keys can target any workspace. Workspace-scoped keys can only access their bound workspace. The CLI --workspace flag handles this automatically.
Tenant Isolation
Section titled “Tenant Isolation”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.
Examples
Section titled “Examples”Remember
Section titled “Remember”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 .Recall (default composite scoring)
Section titled “Recall (default composite scoring)”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 }] }]Recall (pure relevance scoring)
Section titled “Recall (pure relevance scoring)”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.
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 .Get by ID
Section titled “Get by ID”curl -s http://localhost:6381/v1/memories/01KK3S0KXYE22EFF489YRTH559 \ -H "Authorization: Bearer $HEBBS_API_KEY" | jq .Revise
Section titled “Revise”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 .Forget
Section titled “Forget”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 .Insights
Section titled “Insights”curl -s "http://localhost:6381/v1/insights?entity_id=customer-42&max_results=5" \ -H "Authorization: Bearer $HEBBS_API_KEY" | jq .Subscribe (SSE)
Section titled “Subscribe (SSE)”Open a subscription stream:
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):
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:
curl -s -X DELETE http://localhost:6381/v1/subscribe/1 \ -H "Authorization: Bearer $HEBBS_API_KEY"List Memories
Section titled “List Memories”Browse memories with cursor-based pagination and optional filters.
# List first 50 memoriescurl -s "http://localhost:6381/v1/memories?limit=50" \ -H "Authorization: Bearer $HEBBS_API_KEY" | jq .
# Filter by entity and kindcurl -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 responsecurl -s "http://localhost:6381/v1/memories?cursor=01KK3S0KXYE22EFF489YRTH559&limit=20" \ -H "Authorization: Bearer $HEBBS_API_KEY" | jq .Query parameters:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
entity_id | string | No | — | Filter to a specific entity |
kind | string | No | — | Filter by memory kind: episode, insight, revision, document, proposition |
cursor | string | No | — | Hex memory ID; returns memories after this ID (for pagination) |
limit | integer | No | 100 | Max 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.
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.
Batch Get
Section titled “Batch Get”Retrieve multiple memories in a single request.
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:
| Field | Type | Required | Description |
|---|---|---|---|
memory_ids | string[] | Yes | Hex-encoded memory IDs (max 500) |
Response: Array of Memory objects. Missing IDs are silently skipped.
Graph (Subgraph Query)
Section titled “Graph (Subgraph Query)”Query a subgraph centered on a memory node. Returns all nodes and edges within the specified traversal depth.
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:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
center_id | string | Yes | — | Hex memory ID of the center node |
depth | integer | No | 2 | Maximum traversal depth from center (capped at 5) |
edge_types | string[] | No | all types | Edge types to traverse (e.g. ["caused_by", "related_to"]) |
max_nodes | integer | No | 100 | Maximum 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.
Entities
Section titled “Entities”List all entity IDs that have at least one memory.
curl -s http://localhost:6381/v1/entities \ -H "Authorization: Bearer $HEBBS_API_KEY" | jq .Response:
["customer-42", "agent-sales-01", "user-preferences"]Reflect Prepare (Deprecated)
Section titled “Reflect Prepare (Deprecated)”Prepare reflection data without calling any LLM. Returns clustered memories and prompts for agent-driven insight generation.
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:
| Field | Type | Required | Description |
|---|---|---|---|
entity_id | string | No | Entity scope (omit for global) |
since_us | integer | No | Only 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}Reflect Commit (Deprecated)
Section titled “Reflect Commit (Deprecated)”Commit agent-produced insights from a previous reflect/prepare call.
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:
| Field | Type | Required | Description |
|---|---|---|---|
session_id | string | Yes | Session ID from reflect/prepare |
insights | array | Yes | Array of insight objects |
insights[].content | string | Yes | Insight text |
insights[].confidence | float | Yes | Confidence score (0.0–1.0) |
insights[].source_memory_ids | string[] | Yes | Hex-encoded memory IDs from the cluster |
insights[].tags | string[] | No | Categorical labels |
insights[].cluster_id | integer | No | Cluster ID from prepare output |
Response:
{ "insights_created": 1}Sessions expire after 10 minutes. Source memory IDs must be from the original prepare output.
Contradiction Prepare (Deprecated)
Section titled “Contradiction Prepare (Deprecated)”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.
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.
Contradiction Commit (Deprecated)
Section titled “Contradiction Commit (Deprecated)”Commit verdicts for pending contradiction candidates after agent review.
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:
| Field | Type | Required | Description |
|---|---|---|---|
verdicts | array | Yes | Array of verdict objects |
verdicts[].pending_id | string | Yes | Pending candidate ID from prepare |
verdicts[].verdict | string | Yes | "contradiction", "revision", or "dismiss" |
verdicts[].confidence | float | Yes | Agent confidence (0.0—1.0) |
verdicts[].reasoning | string | No | Explanation 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. UseContent-Type: application/jsonfor request bodies. - Memory IDs in REST paths are 32-character hex strings (16 bytes).