> ## Documentation Index
> Fetch the complete documentation index at: https://kremis.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# API Overview

> REST API for Kremis — authentication, rate limiting, and input validation.

**Base URL:** `http://localhost:8080`
**Version:** 0.21.2
**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                                                                  |
| `/certify`        | POST   | Verifiable Query Certificate (reproducible proof of a fact, or proof of absence) |
| `/export`         | POST   | Export graph                                                                     |
| `/hash`           | GET    | BLAKE3 cryptographic hash of graph                                               |
| `/metrics`        | GET    | Prometheus-compatible metrics                                                    |

<Warning>
  The HTTP server holds an exclusive lock on the redb database. CLI commands (`ingest`, `status`, `export`) cannot run while the server is active.
</Warning>

## Authentication

Authentication is **optional**, controlled by the `KREMIS_API_KEY` environment variable.

```bash theme={null}
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`

## Log Format

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. |

```bash theme={null}
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 |

## Input Validation

| 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`                                             |

```json theme={null}
{
  "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`.
