Base URL: http://localhost:8080
Version: 0.16.1
License: Apache 2.0
Endpoints
| Endpoint | Method | Description |
|---|
/health | GET | Health check (always public) |
/status | GET | Graph statistics |
/stage | GET | Developmental stage |
/signal | POST | Ingest a signal |
/signals | POST | Ingest a sequence of signals (creates edges) |
/signal/retract | POST | Retract a signal (decrement edge weight) |
/query | POST | Execute a query |
/export | POST | Export graph |
/hash | GET | BLAKE3 cryptographic hash of graph |
/metrics | GET | Prometheus-compatible metrics |
The HTTP server holds an exclusive lock on the redb database. CLI commands (ingest, status, export) cannot run while the server is active.
Authentication
Authentication is optional, controlled by the KREMIS_API_KEY environment variable.
export KREMIS_API_KEY="your-secret-api-key"
When enabled, include the key in requests:
Authorization: Bearer <your-api-key>
The /health endpoint is always accessible without authentication.
Rate Limiting
- Default: 100 requests per second (global, not per-client)
- Configure:
KREMIS_RATE_LIMIT=200
- Exceeded: returns
429 Too Many Requests
Control the server log output format with KREMIS_LOG_FORMAT:
| Value | Description |
|---|
text (default) | Human-readable log lines |
json | Machine-parseable JSON — one object per line, compatible with Loki, Datadog, etc. |
KREMIS_LOG_FORMAT=json kremis server
Structured log fields (present in both modes, separately filterable in JSON):
| Field | Events |
|---|
event="server_start" | Server bind success |
event="cors_insecure" | KREMIS_CORS_ORIGINS=* detected |
event="auth_failure" | Invalid or missing API key |
event="rate_limit_exceeded" | Request rejected by rate limiter |
| Field | Limit |
|---|
attribute | Max 256 bytes |
value | Max 64 KB (65,536 bytes) |
depth | Max 100 |
nodes (intersect) | Max 100 items |
Error Codes
| Status | Description | Response Type |
|---|
200 | Success | JSON |
400 | Bad Request — invalid input | JSON with error field |
401 | Unauthorized — missing or invalid API key | Plain text |
429 | Too Many Requests — rate limit exceeded | Plain text |
500 | Internal Server Error | JSON with error field |
Query Response: Grounding Field
Every query response includes a grounding field that classifies the result:
| Value | Meaning | Query types |
|---|
"fact" | Data retrieved directly | lookup, properties |
"inference" | Result derived via graph traversal | traverse, traverse_filtered, strongest_path, intersect, related |
"unknown" | No data found | Any query when found: false |
{
"success": true,
"found": true,
"path": [0],
"edges": [],
"grounding": "fact",
"error": null
}
Query Response: Diagnostic Field
When found is false, an optional diagnostic field explains why:
| Value | Meaning |
|---|
"entity_not_found" | lookup: entity ID does not exist |
"node_not_found" | traverse, traverse_filtered, related, properties: node ID does not exist |
"start_not_found" | strongest_path: start node does not exist |
"end_not_found" | strongest_path: end node does not exist |
"no_path" | strongest_path: both nodes exist but no path connects them |
"no_common_neighbors" | intersect: no node is reachable from all inputs |
The diagnostic field is omitted when found is true.