API Reference
Every endpoint on the Nocturnus.AI HTTP server. Start with POST /context — the simplest way to cut your LLM token costs by 97%. Base URL: http://localhost:9300
Common Headers
Content-Type: application/json— required for all POST requestsX-Database: default— selects the logical database (optional, defaults to "default")X-Tenant-ID: <name>— selects the tenant within that database (required on most endpoints; MCP routes default to "default")Authorization: Bearer <key>— required when auth is enabled
Context Management (cost optimization)
| Endpoint | Description |
|---|---|
| POST /context | Simplest API — turns in, facts out. Array of strings → optimized facts |
| POST /context/optimize | Advanced: goal-driven context window with buckets, diversity caps |
| POST /context/diff | Incremental changes since last context window |
| POST /context/summary | Knowledge base summary (predicate counts, contradictions) |
| POST /context/session/clear | Clear diff session state |
| POST /context/ingest | Extract + assert + optimize in one call (requires LLM) |
POST /context — send your conversation turns as an array of strings, get back ranked facts. See the full integration guide → Simplified API
Developer-friendly aliases for the most common operations. These are the endpoints shown in the quickstart.
| Endpoint | Full Form | Description |
|---|---|---|
| POST /tell | POST /assert/fact | Store a fact |
| POST /ask | POST /infer | Query with inference (backward chaining) |
| POST /teach | POST /assert/rule | Define a logical rule |
| POST /forget | POST /retract | Remove a fact (cascading) |
POST /assert/fact (or /tell)
Assert a fact into the knowledge base.
Request
{
"predicate": "parent",
"args": ["alice", "bob"],
"truthVal": true,
"scope": null,
"ttl": null,
"validUntil": null,
"metadata": {}
} Only predicate and args are required. All other fields are optional.
Response
{ "status": "ok", "atom": "parent(alice, bob)" } POST /assert/rule (or /teach)
Define a logical rule for inference.
Request
{
"head": { "predicate": "grandparent", "args": ["?x", "?z"] },
"body": [
{ "predicate": "parent", "args": ["?x", "?y"] },
{ "predicate": "parent", "args": ["?y", "?z"] }
],
"scope": null
} POST /infer (or /ask)
Run backward-chaining inference. Use ?-prefixed variables for unknowns.
Request
{
"predicate": "grandparent",
"args": ["?who", "charlie"],
"scope": null
} To get the full derivation chain showing how each result was derived, use POST /ask (the simplified alias) which accepts withProof in the JSON body:
{
"predicate": "grandparent",
"args": ["?who", "charlie"],
"withProof": true
} Response
{ "results": ["grandparent(alice, charlie)"] } POST /query
Direct pattern matching without inference (no rule application). Reads the Hexastore directly — faster than /infer when you only need stored facts and don't need derived conclusions.
Request
{
"predicate": "parent",
"args": ["?who", "bob"],
"scope": null
} Response
[
{ "predicate": "parent", "args": ["alice", "bob"], "truthVal": true }
] POST /retract (or /forget)
Remove a fact. The TMS automatically cascade-retracts any derived conclusions that depended on it.
Request
{
"predicate": "parent",
"args": ["alice", "bob"]
} ACID Transactions
Group multiple operations into an atomic unit. If any operation fails, the entire transaction rolls back — ensuring consistency when multiple agents write simultaneously.
# 1. Begin transaction
TX_ID=$(curl -s -X POST http://localhost:9300/tx/begin | jq -r '.id')
# 2. Assert facts within the transaction
curl -X POST http://localhost:9300/assert/fact \
-H "Content-Type: application/json" \
-H "X-Transaction-ID: $TX_ID" \
-d '{"predicate":"balance","args":["alice","500"]}'
curl -X POST http://localhost:9300/assert/fact \
-H "Content-Type: application/json" \
-H "X-Transaction-ID: $TX_ID" \
-d '{"predicate":"balance","args":["bob","300"]}'
# 3. Commit (or rollback)
curl -X POST "http://localhost:9300/tx/commit/$TX_ID"
# curl -X POST "http://localhost:9300/tx/rollback/$TX_ID" POST /extract
LLM-powered fact extraction from natural language text. See LLM Integration for details.
Request
{
"text": "Acme Corp is on the enterprise plan.",
"assert": true,
"rules": false,
"scope": null,
"context": null
} POST /synthesize
LLM-powered natural language question answering grounded in facts. See LLM Integration.
Request
{
"question": "What plan is Acme Corp on?",
"scope": null
} Response
{
"answer": "Acme Corp is on the enterprise plan.",
"derivation": [{ "fact": "subscription_tier(acme_corp, enterprise)", "type": "fact_match" }],
"confidence": 0.95,
"queriesExecuted": ["subscription_tier(acme_corp, ?tier)"],
"provider": "anthropic",
"model": "claude-sonnet-4-20250514"
} Memory Endpoints
GET /memory/context
Get the top-K most salient facts for the agent's context window.
{
"maxFacts": 100,
"minSalience": 0.0,
"predicates": null,
"scope": null
} POST /memory/consolidate
Compress repetitive episodic patterns into semantic summaries.
POST /memory/decay
Evict expired and low-salience facts.
{ "threshold": 0.05 } Context Management Engine
The context optimization API — the core of NocturnusAI's cost reduction story. These endpoints deliver goal-driven, salience-ranked, contradiction-checked context windows that cut token costs by 97%.
POST /context
The simplest way to use NocturnusAI. Pass an array of conversation turns (strings), get back relevant facts. NocturnusAI extracts, stores, deduplicates, and ranks automatically.
Request
{
"turns": [
"Acme Corp is on the enterprise plan and based in Austin.",
"They have a $2M contract with 24/7 SLA support."
],
"maxFacts": 50,
"scope": null
} Only turns is required. maxFacts defaults to 50. scope is optional for data isolation.
Response
{
"facts": [
{ "predicate": "customer_tier", "args": ["acme_corp", "enterprise"], "salience": 0.95, "provenance": null },
{ "predicate": "location", "args": ["acme_corp", "austin"], "salience": 0.88, "provenance": null },
{ "predicate": "contract_value", "args": ["acme_corp", "2000000"], "salience": 0.92, "provenance": null },
{ "predicate": "sla_tier", "args": ["acme_corp", "24_7"], "salience": 0.90, "provenance": null }
],
"totalFactsInKB": 127,
"factsReturned": 4,
"contradictions": 0,
"newFactsExtracted": 4
} Feed the facts array directly into your LLM's system prompt. See the Context Optimization guide for full integration examples with OpenAI, Claude, LangChain, and MCP.
POST /context/optimize
Build an optimized context window. Optionally goal-driven via backward chaining.
Request
{
"maxFacts": 25,
"goals": [
{ "predicate": "enforceable", "args": ["contract_001"] },
{ "predicate": "exception_applies", "args": ["contract_001", "?e"] }
],
"relevanceBuckets": [
{ "name": "contract", "predicates": ["contract_type", "contract_value"], "maxFacts": 8 },
{ "name": "legal", "predicates": ["enforceable", "statute_of_frauds"], "maxFacts": 10 }
],
"scope": null,
"predicates": null,
"sessionId": "session-42",
"autoResolveContradictions": true,
"maxFactsPerPredicate": null
} | Field | Type | Default | Description |
|---|---|---|---|
| maxFacts | int? | 100 | Maximum facts in the context window |
| goals | GoalSpec[]? | null | Goal atoms for backward chaining. Each has predicate, args, optional negated |
| relevanceBuckets | Bucket[]? | null | Per-domain budgets: name, predicates, weight, maxFacts |
| scope | string? | null | Restrict to facts in this scope |
| predicates | string[]? | null | Filter to specific predicate names |
| sessionId | string? | null | Session ID for incremental diffs (stores snapshot) |
| autoResolveContradictions | boolean | true | Auto-resolve contradictions (keeps higher-salience fact) |
| maxFactsPerPredicate | int? | null | Diversity cap — max facts per predicate type |
Response
{
"windowId": "ctx-a7f3b2e1",
"entries": [
{
"predicate": "enforceable",
"args": ["contract_001"],
"negated": false,
"scope": null,
"salience": 0.98,
"category": "goal_relevant",
"charCount": 28,
"provenance": {
"rule": "enforceable(?c) :- signed(?c), consideration(?c)",
"premises": ["signed(contract_001)", "consideration(contract_001)"]
},
"createdAt": 1712180400000,
"validFrom": null,
"validUntil": null,
"metadata": {}
}
],
"relevantRules": ["enforceable(?c) :- signed(?c), consideration(?c)"],
"totalFactsAvailable": 512,
"totalFactsIncluded": 15,
"deduplicationSavings": 3,
"contradictionsFound": 1,
"contradictionsResolved": 1,
"contradictions": [
{
"predicate": "valid_until",
"args": ["contract_001", "2024-12"],
"positiveSalience": 0.7,
"negativeSalience": 0.3
}
],
"bucketStats": {
"contract": { "factsIncluded": 6, "maxAllocation": 8, "minSalience": 0.45, "maxSalience": 0.98 },
"legal": { "factsIncluded": 9, "maxAllocation": 10, "minSalience": 0.52, "maxSalience": 0.98 }
},
"totalCharCount": 820,
"goalDriven": true,
"knowledgeGeneration": 47,
"generatedAt": 1712180450000
} POST /context/diff
Get incremental changes since a previous context window. Requires a sessionId that was used in a prior /context/optimize call. Only sends what changed — further reducing token spend on multi-turn conversations.
Request
{
"sessionId": "session-42",
"maxFacts": 25,
"scope": null,
"goals": [{ "predicate": "enforceable", "args": ["contract_001"] }]
} Response
{
"previousWindowId": "ctx-a7f3b2e1",
"currentWindowId": "ctx-b8g4c3f2",
"added": [
{ "predicate": "amendment", "args": ["contract_001", "clause_7"], "salience": 0.91, "category": "goal_relevant", "charCount": 38 }
],
"removed": [
{ "key": "valid_until/contract_001/2024-12", "predicate": "valid_until", "args": ["contract_001", "2024-12"], "negated": false, "scope": null }
],
"unchanged": 14,
"fullRefreshRecommended": false,
"reason": null
} POST /context/summary
Get a compact summary of the knowledge base — predicate counts, expiring facts, contradictions, and top salient facts. Useful for dashboard views and monitoring.
Request
{ "scope": null } Response
{
"totalFacts": 512,
"predicateCount": 23,
"topPredicates": [
{ "predicate": "contract_type", "count": 87 },
{ "predicate": "customer_tier", "count": 64 }
],
"factsWithTtl": 45,
"factsExpiringWithin1h": 12,
"contradictions": 3,
"topSalientFacts": [],
"totalCharCount": 24500,
"knowledgeGeneration": 47,
"generatedAt": 1712180450000
} POST /context/session/clear
Clear session state used for context diffing. Call this when a conversation ends or to reset diff tracking.
Request
{ "sessionId": "session-42" } Response
Session 'session-42' cleared POST /context/ingest
One-shot pipeline: extract facts from text (via LLM or predicate syntax), assert them, and return an optimized context window — all in a single request. Requires LLM extraction to be enabled for natural language input.
Request
{
"text": "Acme Corp signed contract #001 for $2M. The contract includes an arbitration clause.",
"goals": [{ "predicate": "enforceable", "args": ["contract_001"] }],
"maxFacts": 25,
"scope": null,
"sessionId": "session-42",
"autoResolveContradictions": true,
"contextHint": "Legal contract analysis"
} Response
{
"extracted": [
{ "predicate": "contract_signed", "args": ["acme_corp", "contract_001"], "confidence": 0.95 },
{ "predicate": "contract_value", "args": ["contract_001", "2000000"], "confidence": 0.92 },
{ "predicate": "has_clause", "args": ["contract_001", "arbitration"], "confidence": 0.88 }
],
"extractionProvider": "anthropic",
"context": {
"windowId": "ctx-c9h5d4g3",
"entries": [...],
"totalFactsAvailable": 515,
"totalFactsIncluded": 18,
"totalCharCount": 940,
"goalDriven": true
}
} Admin Endpoints
| Endpoint | Description |
|---|---|
| GET /health | Health check (Kubernetes liveness) |
| GET /health/ready | Readiness check |
| GET /predicates | Discover knowledge base schema |
| GET /databases | List all databases |
| POST /databases | Create a new database |
| GET /metrics | Prometheus metrics |
| POST /tx/begin | Begin ACID transaction |
| POST /tx/commit/:id | Commit transaction |
| POST /tx/rollback/:id | Rollback transaction |
| GET /admin/databases/:name/tenants | List tenants in a database |
| POST /admin/databases/:name/tenants | Create a tenant |
| DELETE /admin/databases/:name/tenants/:id | Delete a tenant and all its data |
| POST /admin/databases/:name/nuke | Delete all data in a database |
| POST /admin/databases/:name/tenants/:id/nuke | Delete all data in a tenant |
Scope Management
Scopes are logical partitions within a tenant for hypothetical reasoning, versioning, and A/B testing. Use Git-like fork/diff/merge operations to branch knowledge.
| Endpoint | Description |
|---|---|
| POST /scope/fork | Fork a scope — copies all facts from source to a new scope |
| POST /scope/diff | Diff two scopes — shows added/removed/modified facts |
| POST /scope/merge | Merge scopes with strategy: SOURCE_WINS, TARGET_WINS, KEEP_BOTH, REJECT |
| DELETE /scope/:name | Delete a scope and all its facts |
| GET /scopes | List all scopes in the current tenant |
Aggregation & Bulk Operations
| Endpoint | Description |
|---|---|
| POST /aggregate | Aggregation queries: COUNT, SUM, MIN, MAX, AVG on fact arguments |
| POST /assert/facts | Bulk assert — submit an array of facts in a single request |
| POST /retract/pattern | Pattern-based retraction — remove all facts matching a pattern |