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


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)
New to NocturnusAI? Start with 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%.

This is the money saver. Instead of stuffing 150K tokens into every LLM prompt ($2.25/request at GPT-4o rates), these endpoints deliver ~820 tokens of goal-relevant facts ($0.01/request). Same correct answer, 97% lower bill.

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

What's Next?

SDKs →

Python and TypeScript client libraries

MCP Integration →

JSON-RPC 2.0 protocol for agent tools

Core Concepts →

Understand the logic model behind the API