Skip to content

REST API

contextdb exposes a REST API on port 7701.

Endpoints

MethodPathDescription
POST/v1/namespaces/{ns}/writeWrite a node
POST/v1/namespaces/{ns}/retrieveRetrieve nodes
POST/v1/namespaces/{ns}/ingestIngest text (LLM extraction)
GET/v1/namespaces/{ns}/nodes/{id}Get a single node
POST/v1/namespaces/{ns}/sources/labelLabel a source
GET/v1/statsRuntime statistics
GET/v1/pingHealth check

Authentication

Pass a Bearer token in the Authorization header. The token format is tenant:permissions:secret:

bash
curl -X POST http://localhost:7701/v1/namespaces/my-app/write \
  -H "Authorization: Bearer acme-corp:write:sk-secret" \
  -H "Content-Type: application/json" \
  -d '{"content": "...", "source_id": "..."}'

See RBAC for details on the token format and permission model.

Write

bash
curl -X POST http://localhost:7701/v1/namespaces/my-app/write \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "general",
    "content": "Go 1.22 added routing patterns to net/http",
    "source_id": "docs-crawler",
    "labels": ["Claim"],
    "vector": [0.1, 0.2, 0.3],
    "confidence": 0.9
  }'

Response:

json
{
  "node_id": "550e8400-e29b-41d4-a716-446655440000",
  "admitted": true
}

Rejected write:

json
{
  "node_id": "00000000-0000-0000-0000-000000000000",
  "admitted": false,
  "reason": "source credibility below floor (< 0.05)"
}

Write with conflict:

json
{
  "node_id": "550e8400-e29b-41d4-a716-446655440000",
  "admitted": true,
  "conflict_ids": ["660e8400-e29b-41d4-a716-446655440001"]
}

Request fields

FieldTypeRequiredDescription
modestringNoNamespace mode: general, belief_system, agent_memory, procedural
contentstringYesText content (auto-embedded if no vector provided and server has embedder)
source_idstringYesExternal source identifier
labelsstring[]NoNode labels
propertiesobjectNoArbitrary metadata
vectorfloat[]NoPre-computed embedding
model_idstringNoEmbedding model identifier
confidencefloatNoConfidence [0, 1]
valid_fromstringNoISO 8601 timestamp
mem_typestringNoMemory type: episodic, semantic, procedural, working

Retrieve

bash
curl -X POST http://localhost:7701/v1/namespaces/my-app/retrieve \
  -H "Content-Type: application/json" \
  -d '{
    "vector": [0.1, 0.2, 0.3],
    "top_k": 5,
    "score_params": {
      "similarity_weight": 0.5,
      "confidence_weight": 0.3,
      "recency_weight": 0.15,
      "utility_weight": 0.05
    }
  }'

Text-based query

Send text instead of vector to have the server auto-embed the query:

bash
curl -X POST http://localhost:7701/v1/namespaces/my-app/retrieve \
  -H "Content-Type: application/json" \
  -d '{
    "text": "What changed in Go 1.22?",
    "top_k": 5
  }'

Label filtering

Filter results to nodes with all specified labels:

bash
curl -X POST http://localhost:7701/v1/namespaces/my-app/retrieve \
  -H "Content-Type: application/json" \
  -d '{
    "text": "routing patterns",
    "labels": ["Claim", "Verified"],
    "top_k": 10
  }'

Response:

json
{
  "results": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "namespace": "my-app",
      "labels": ["Claim"],
      "properties": {"text": "Go 1.22 added routing patterns to net/http"},
      "score": 0.87,
      "similarity_score": 0.95,
      "confidence_score": 0.9,
      "recency_score": 0.72,
      "utility_score": 0.5,
      "retrieval_source": "vector"
    }
  ]
}

Request fields

FieldTypeRequiredDescription
vectorfloat[]For vector searchQuery embedding
vectorsfloat[][]For multi-vectorMultiple query embeddings fused
textstringFor text searchAuto-embedded server-side
seed_idsstring[]For graph walkKnown relevant node IDs
top_kintNoMax results (default: 10)
labelsstring[]NoFilter to nodes with all specified labels
score_paramsobjectNoOverride scoring weights
as_ofstringNoISO 8601 timestamp for point-in-time query

Ingest Text

bash
curl -X POST http://localhost:7701/v1/namespaces/my-app/ingest \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "general",
    "text": "Alice knows Go and Python. Bob specializes in Rust.",
    "source_id": "docs-crawler"
  }'

Response:

json
{
  "nodes_written": 4,
  "edges_written": 3,
  "rejected": 0
}

Get Node

bash
curl http://localhost:7701/v1/namespaces/my-app/nodes/550e8400-e29b-41d4-a716-446655440000

Label Source

bash
curl -X POST http://localhost:7701/v1/namespaces/my-app/sources/label \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "belief_system",
    "external_id": "moderator:alice",
    "labels": ["moderator"]
  }'

Response:

json
{"status": "ok"}

Stats

bash
curl http://localhost:7701/v1/stats

Response:

json
{
  "Mode": "embedded",
  "RetrievalTotal": 142,
  "RetrievalErrors": 0,
  "IngestTotal": 500,
  "IngestAdmitted": 487,
  "IngestRejected": 13,
  "LatencyP50Us": 450.5,
  "LatencyP95Us": 1200.3,
  "LatencyMeanUs": 520.1
}

Health Check

bash
curl http://localhost:7701/v1/ping

Response:

json
{"status": "ok"}

Multi-tenancy

Pass X-Tenant-ID header to isolate data:

bash
curl -X POST http://localhost:7701/v1/namespaces/my-app/write \
  -H "X-Tenant-ID: acme-corp" \
  -H "Content-Type: application/json" \
  -d '{"content": "...", "source_id": "..."}'

Or use Bearer token prefix (recommended for production):

bash
curl -X POST http://localhost:7701/v1/namespaces/my-app/write \
  -H "Authorization: Bearer acme-corp:write:sk-secret" \
  -H "Content-Type: application/json" \
  -d '{"content": "...", "source_id": "..."}'

Admin UI

The admin dashboard is served on the observe port (7702):

bash
# Dashboard
open http://localhost:7702/admin/

# Admin stats API
curl http://localhost:7702/admin/api/stats

The dashboard displays ingest/retrieval counters, error rates, and links to metrics and profiling endpoints.

Observability

Metrics and health are on port 7702:

bash
# Prometheus metrics
curl http://localhost:7702/metrics

# pprof
curl http://localhost:7702/debug/pprof/

# Health
curl http://localhost:7702/healthz

Released under the MIT License.