Axiom REST API
nyxCore Axiom RAG API — Integration Guide for External Systems
1. Overview
nyxCore Axiom is a project-scoped document knowledge system with hybrid search (vector similarity + full-text). External systems access it via a REST API authenticated with nyx_ax_ bearer tokens.
Base URL: https://nyxcore.cloud
Authentication: Bearer token with nyx_ax_ prefix
2. Authentication
All requests require a Bearer token in the Authorization header:
Authorization: Bearer nyx_ax_<token>
Token format: nyx_ax_ prefix + 32 bytes base64url (total ~55 chars)
Token scopes (assigned at creation):
| Scope | Permission |
|---|---|
search |
Search documents (also implies read) |
read |
List documents |
upload |
Ingest/upload new documents |
Project-scoped tokens: If the token was created for a specific project, all requests are automatically scoped to that project's documents. You don't need to pass projectId in requests — the token enforces it.
Rate limits:
- 100 requests/minute per tenant
- Fail-open (requests allowed if Redis is unavailable)
3. Endpoints
3.1 Search Documents
The primary endpoint for RAG retrieval. Uses hybrid search: 70% vector similarity (pgvector cosine distance) + 30% full-text (PostgreSQL tsvector), with authority-level score boosting.
POST /api/v1/rag/search
Authorization: Bearer nyx_ax_<token>
Content-Type: application/json
Request body:
{
"query": "Wie funktioniert das Onboarding für neue Mitarbeiter?",
"limit": 10,
"authority": ["mandatory", "guideline"]
}
| Field | Type | Required | Description |
|---|---|---|---|
query |
string | yes | Search query (1-500 chars) |
limit |
number | no | Max results (1-50, default: 10) |
projectId |
string (UUID) | no | Filter to specific project. Ignored if token is project-scoped. |
authority |
string[] | no | Filter by authority level: "mandatory", "guideline", "informational" |
Response (200):
{
"ok": true,
"results": [
{
"content": "## Onboarding Prozess\n\nNeue Mitarbeiter erhalten am ersten Tag...",
"heading": "Onboarding Prozess",
"filename": "hr-handbuch.md",
"authority": "guideline",
"score": 0.847,
"chunkId": "abc-123",
"documentId": "def-456"
}
],
"requestId": "req-789"
}
Score composition:
score = (vector_similarity * 0.7) + (text_rank * 0.3) + authority_boost
authority_boost:
mandatory: +0.3 (GDPR, ISO, legal — always highest priority)
guideline: +0.15 (conventions, standards)
informational: +0.0 (general context)
Fallback behavior: If embedding generation fails (e.g., no OpenAI key configured for tenant), the search automatically falls back to text-only search.
3.2 List Documents
List all documents available in the knowledge base.
GET /api/v1/rag/documents
Authorization: Bearer nyx_ax_<token>
Query parameters:
| Param | Type | Required | Description |
|---|---|---|---|
projectId |
string (UUID) | no | Filter to specific project. Ignored if token is project-scoped. |
Response (200):
{
"ok": true,
"documents": [
{
"id": "def-456",
"filename": "hr-handbuch.md",
"mimeType": "text/markdown",
"fileSize": 24576,
"sourceUrl": null,
"status": "ready",
"chunkCount": 12,
"authority": "guideline",
"category": "workflow",
"createdAt": "2026-03-10T14:30:00.000Z"
}
],
"requestId": "req-101"
}
Document status values:
| Status | Meaning |
|---|---|
pending |
Uploaded, not yet processed |
processing |
Chunking + embedding in progress |
ready |
Searchable |
failed |
Processing failed (check errorMessage) |
3.3 Upload Documents
Ingest a new document into the knowledge base. Processing (chunking, embedding) happens asynchronously.
POST /api/v1/rag/ingest
Authorization: Bearer nyx_ax_<token>
Content-Type: multipart/form-data
Form fields:
| Field | Type | Required | Description |
|---|---|---|---|
file |
File | yes | The document file |
projectId |
string (UUID) | conditional | Required if token is tenant-wide; ignored if token is project-scoped |
filename |
string | no | Override filename (defaults to file.name) |
authority |
string | no | "informational" (default), "guideline", or "mandatory" |
category |
string | no | "general" (default), "workflow", "coding", "compliance", "style" |
Supported file types: .md, .txt, .pdf, .ts, .js, .py, .json, .yaml, .toml, .html, .css
Response (202 Accepted):
{
"ok": true,
"documentId": "new-doc-123",
"status": "processing",
"requestId": "req-202"
}
After upload, poll GET /api/v1/rag/documents to check when status becomes "ready".
4. Error Responses
All errors follow a consistent format:
{
"ok": false,
"error": {
"code": "UNAUTHORIZED",
"message": "Missing or invalid Axiom API token"
},
"requestId": "req-err-1"
}
| HTTP Status | Code | Meaning |
|---|---|---|
| 400 | VALIDATION_ERROR |
Invalid JSON, missing fields, unsupported file type |
| 401 | UNAUTHORIZED |
Missing/invalid/expired bearer token |
| 403 | FORBIDDEN |
Token lacks required scope |
| 429 | RATE_LIMITED |
Rate limit exceeded (100 req/min) |
5. Integration Examples
5.1 Python (OnboardingTutor / miniRAG)
import requests
AXIOM_BASE = "https://nyxcore.cloud"
AXIOM_TOKEN = "nyx_ax_..." # from nyxCore dashboard
def search_axiom(query: str, limit: int = 5, authority: list[str] | None = None) -> list[dict]:
"""Search nyxCore Axiom knowledge base."""
resp = requests.post(
f"{AXIOM_BASE}/api/v1/rag/search",
headers={
"Authorization": f"Bearer {AXIOM_TOKEN}",
"Content-Type": "application/json",
},
json={
"query": query,
"limit": limit,
**({"authority": authority} if authority else {}),
},
)
resp.raise_for_status()
data = resp.json()
return data["results"]
def build_context(user_question: str) -> str:
"""Build RAG context from Axiom for injection into LLM prompt."""
# 1. Always load mandatory rules first
mandatory = search_axiom(user_question, limit=5, authority=["mandatory"])
# 2. Then search guidelines + informational
general = search_axiom(user_question, limit=10)
# 3. Assemble context with authority headers
context_parts = []
for chunk in mandatory:
context_parts.append(
f"[MANDATORY — {chunk['filename']}]\n{chunk['content']}"
)
for chunk in general:
if chunk["chunkId"] not in {c["chunkId"] for c in mandatory}:
context_parts.append(
f"[{chunk['authority'].upper()} — {chunk['filename']}]\n"
f"{chunk['content']}"
)
return "\n\n---\n\n".join(context_parts)
5.2 TypeScript / Node.js
const AXIOM_BASE = "https://nyxcore.cloud";
const AXIOM_TOKEN = process.env.AXIOM_TOKEN!; // nyx_ax_...
interface AxiomChunk {
content: string;
heading: string | null;
filename: string;
authority: "mandatory" | "guideline" | "informational";
score: number;
chunkId: string;
documentId: string;
}
async function searchAxiom(
query: string,
options?: { limit?: number; authority?: string[] }
): Promise<AxiomChunk[]> {
const res = await fetch(`${AXIOM_BASE}/api/v1/rag/search`, {
method: "POST",
headers: {
Authorization: `Bearer ${AXIOM_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
query,
limit: options?.limit ?? 10,
...(options?.authority && { authority: options.authority }),
}),
});
if (!res.ok) {
const err = await res.json().catch(() => null);
throw new Error(
`Axiom search failed: ${res.status} ${err?.error?.message ?? ""}`
);
}
const data = await res.json();
return data.results;
}
// Format results for LLM context injection
async function buildAxiomContext(userQuery: string): Promise<string> {
const chunks = await searchAxiom(userQuery, {
limit: 8,
authority: ["mandatory", "guideline"],
});
return chunks
.map(
(c) =>
`### ${c.heading ?? c.filename} [${c.authority}]\n${c.content}`
)
.join("\n\n");
}
5.3 curl (Quick Testing)
# Search
curl -X POST https://nyxcore.cloud/api/v1/rag/search \
-H "Authorization: Bearer nyx_ax_YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"query": "GDPR data retention", "limit": 5}'
# List documents
curl https://nyxcore.cloud/api/v1/rag/documents \
-H "Authorization: Bearer nyx_ax_YOUR_TOKEN"
# Upload a document
curl -X POST https://nyxcore.cloud/api/v1/rag/ingest \
-H "Authorization: Bearer nyx_ax_YOUR_TOKEN" \
-F "file=@./my-doc.md" \
-F "authority=guideline"
