Human guide · API v1
Give AletheionAGI a question. Get safe evidence back.
Start with the tiny version below. You only need the longer sections when you are ready to configure users, namespaces and production security.
Start here
Imagine a notebook that checks answers.
You only need to understand two moments: first you teach the notebook the trusted information; later your users ask questions about it.
1. Teach the notebook
Send trusted policies, product facts and approved information to POST /v1/memories. AletheionAGI stores and indexes them.
Write one small, clear fact that your own system is allowed to trust later.
- A customer preference they explicitly gave you:
“This customer prefers blue, lightweight backpacks.” - A confirmed purchase:
“Order 1042 was paid and delivered: wireless mouse, black, on 2026-08-13.” - A trusted product fact:
“Mouse model M-200 is in stock, costs R$ 89.90 and has a two-year warranty.” - A current policy or operational rule:
“Returns are accepted within 30 days when the item is unused.”
You do not repeat this for every customer question. You send the information again only when it is new or has changed.
Code to teach the notebook
// This code runs on your server, never in the browser.
const response = await fetch("https://api.aletheionagi.com/v1/memories", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.ALETHEION_API_KEY}`,
"Content-Type": "application/json",
// A new value every time your server creates a new memory.
"Idempotency-Key": crypto.randomUUID(),
},
body: JSON.stringify({
memory_id: `purchase:${order.id}`,
namespace_id: process.env.ALETHEION_NAMESPACE_ID,
occurred_at: new Date().toISOString(),
content: "Order 1042 was paid and delivered: wireless mouse, black.",
content_type: "text/plain",
source_id: "orders:1042",
authorization_labels: ["customer", "approved"],
}),
});
const memory = await response.json();
// "pending" means AletheionAGI is indexing it. Later it becomes "indexed".
return memory;What must be sent?
Required request headers: Authorization with your server API key and a new Idempotency-Key for this write. The idempotency key makes a safe retry possible if the network fails.
memory_id *Your stable name for this fact, such as purchase:1042. Reuse it to update the same memory later.namespace_id *Copy a managed namespace from the dashboard or derive an authorized delegated ID, such as customer:550e8400-e29b-41d4-a716-446655440000.occurred_at *When the fact became true, in an ISO timestamp with a timezone, such as 2026-08-13T12:00:00Z.content *The trusted fact itself. It must be a non-empty string.content_type *A name for the format, usually text/plain.source_id *Where your backend got the fact, such as orders:1042 or catalog:mouse-m200.authorization_labelsOptional access labels, such as ["customer", "approved"]. Use them when your authorization policy needs an extra boundary.metadataOptional free-form string-to-string notes, such as { version: "1" }. Do not put secrets or unverified user text here.Open does not mean unstructured: you choose your own IDs, labels and metadata keys, but IDs and labels must be short stable identifiers: letters, numbers, ., _, :, / or -. Unknown extra JSON fields are rejected so mistakes do not silently change the stored record.
2. Ask the notebook
Take the text typed by your user and send it to POST /v1/ground. AletheionAGI finds the right memories, asks your configured BYOK reader to write an answer, checks that answer with the Bridge and returns it.
Your application displays grounded_answer to the user. That is the whole everyday flow.
Code to ask the notebook
// This code runs on your server, never in the browser.
const response = await fetch("https://api.aletheionagi.com/v1/ground", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.ALETHEION_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
namespace_id: process.env.ALETHEION_NAMESPACE_ID,
input: userInput,
}),
});
const { grounded_answer } = await response.json();
// Show the checked answer to the user.
return grounded_answer;Do not put the user's question in /v1/memories. A memory is something trusted that the system may use later. A question is only a request for an answer. Mixing them would teach the notebook that every question is a fact.
Before you write a preference or purchase: your own backend must know who it belongs to, why it is correct and who may use it. Never turn an unverified chat message, a model guess or a private detail from another customer into a memory.
Advanced option: POST /v1/queries returns authorized evidence without invoking the reader. Use it only when your own backend needs to control reader inference itself.
Start here
What AletheionAGI does—and what it does not.
Your AI already has a reader: the model that writes the final answer. AletheionAGI sits before that reader. It stores approved memory, finds the evidence relevant to a question and decides whether that evidence is safe enough to support delivery.
Finds and governs evidence
- Stores canonical memory
- Separates companies and namespaces
- Retrieves relevant authorized evidence
- Blocks or abstains when evidence is unsafe
- Records usage and audit events
Owns the reader and experience
- Chooses and pays for the reader model
- Keeps the reader API key
- Defines users and access policy
- Sends approved source material
- Respects AletheionAGI's delivery decision
A fact, policy or event your company deliberately stores.
A boundary that groups data that may be retrieved together.
Your LLM or model that produces the final response.
One completed evaluation of retrieved evidence.
01
The integration in four steps.
Your backend makes two essential kinds of calls: one to store approved information and another to find evidence for a question. Nothing sensitive should be called directly from the browser.
An organization membership is established first. Activation then creates the default project plus Sandbox and Production; an owner issues the server key.
Your backend sends facts, policies or events with their source and access labels.
Your backend sends the question and namespace. AletheionAGI returns eligible evidence.
Your reader writes the answer only when the grounding decision permits it.
02
Connect your backend, not the browser.
Your Aletheion API key identifies the company, project and environment allowed to make the request. Treat it like a password for your server. A person using your website should never see or submit this key.
Store ALETHEION_API_KEY in your backend platform's secret manager. Use a different key for staging and production.
Do not place the key in NEXT_PUBLIC_*, mobile app code, browser JavaScript, logs, screenshots or support messages.
02A
Separate portal users from your application users.
There are two identity planes. Portal users are people on your staff who administer the Aletheion account. Your product's users, buyers, patients, agents or visitors remain in your own identity system and do not register with Aletheion.
Your Aletheion organization
- Owner: controls the organization and production access
- Admin: manages environments, namespaces and server keys
- Member/operator: receives only the portal access explicitly assigned
- Use individual staff accounts; never share an owner login
Your users and teams
- Your authentication system remains authoritative
- Your backend verifies the current user or team
- Your backend maps that identity to a stable namespace
- Anonymous visitors can use a stable pseudonymous journey ID
Teams: use a separate project when an application needs independent credentials and lifecycle. Usage credits and billing currently belong to the organization, not to an individual project. Use a namespace when several users are intentionally allowed to retrieve the same evidence inside one project.
02B
Choose managed or delegated namespaces.
The authorization hierarchy is organization → project → environment → namespace. The API key fixes the first three levels. A request may select only a namespace inside that fixed boundary; it cannot choose another company.
The legal/customer account that owns usage and billing.
An application or team requiring independent keys and lifecycle.
The automatically provisioned Sandbox or Production stage.
The smallest evidence boundary addressable by writes and queries.
API key suppliesorganization_id, project_id and environment_id. Never trust these authority fields from a public request body.Your request suppliesOnly the authorized namespace_id for the current customer, team, journey or knowledge boundary.Register known boundaries
- Open Dashboard → Namespaces.
- Select the project and environment.
- Enter a stable
<kind>:<uuid>identifier and human-readable name. - Create a key without
namespace:provision.
Unknown namespaces fail closed. Use this for a bounded list of departments, assistants, knowledge bases or regulated datasets.
Create application identities on demand
- Open Dashboard → API keys.
- Select only the necessary memory/query permissions.
- Define prefixes from your own domain and enable
namespace:provision. - Keep the key in your backend and send stable IDs on first use.
Creation is idempotent and remains inside the key's tenant and environment. AletheionAGI does not prescribe concepts such as buyer, patient or ticket; the integrating company defines its vocabulary.
API-key scopes
memory:readRetrieve eligible memories from an existing authorized namespacememory:writeStore canonical memory; does not by itself delegate namespace creationmemory:deleteDelete or invalidate memory through the supported lifecyclequery:executeExecute and meter grounding queriesusage:readRead balances and usage for the credential's organizationnamespace:provisionIdempotently create valid subordinate namespaces on first write or queryLeast privilege: a fixed internal assistant normally does not need namespace:provision. A multi-user application often does. Issue one server key per application and environment, and rotate it when ownership or deployment changes.
Map your domain identities in the backend
// server/aletheion-identity.ts
// Your application owns users and sessions. Aletheion receives only a stable,
// pseudonymous namespace ID selected by your trusted backend.
type GroundingSubject =
| { kind: "customer"; customerId: string }
| { kind: "workspace"; workspaceId: string }
| { kind: "session"; sessionId: string };
export function namespaceFor(subject: GroundingSubject): string {
// Every source ID must be a UUID generated and persisted by your application.
// Never put an email address, phone number or display name in a namespace ID.
if (subject.kind === "customer") return "customer:" + subject.customerId;
if (subject.kind === "workspace") return "workspace:" + subject.workspaceId;
return "session:" + subject.sessionId;
}
// Use the resulting namespace in both memory writes and grounding queries.
// A key with namespace:provision creates it idempotently on first use, but only
// inside the organization, project and environment already bound to that key.
const namespaceId = namespaceFor({
kind: "session",
sessionId: "018f5f42-55f1-7d3a-a2ca-8f44b73a9c10",
});Privacy: namespace IDs are selectors, not profiles. Use opaque UUIDs. Never encode email, tax identifiers, phone number, name, prompt text or reader credentials in them.
Identity transition: do not silently copy evidence between anonymous and authenticated namespaces. Linking, promotion or deletion requires an explicit consent and retention policy in your application.
03
Copy a complete server implementation.
Set three environment variables in your backend. Copy the namespace ID from the dashboard or derive it under an approved delegated prefix. The API key and namespace selector must never be committed to Git or exposed to browser code.
ALETHEION_BASE_URL=https://api.aletheionagi.com
ALETHEION_API_KEY=<key-issued-in-your-dashboard>
ALETHEION_NAMESPACE_ID=support:550e8400-e29b-41d4-a716-446655440000Uses the native fetch, a 30-second timeout and one shared authenticated helper.
// server/aletheion.ts
// Keep this module on your backend. Importing it into browser code would expose
// the customer API key and allow unauthorized requests from end-user devices.
// Allow staging or local environments to override the API host. Production uses
// AletheionAGI's stable public domain by default.
const ALETHEION_BASE_URL =
process.env.ALETHEION_BASE_URL ??
"https://api.aletheionagi.com";
// Read the organization-scoped credential from the server environment. AletheionAGI
// issues this key after provisioning; never hard-code or commit its plaintext value.
const ALETHEION_API_KEY = process.env.ALETHEION_API_KEY;
if (!ALETHEION_API_KEY) throw new Error("ALETHEION_API_KEY is missing");
const ALETHEION_NAMESPACE_ID = process.env.ALETHEION_NAMESPACE_ID;
if (!ALETHEION_NAMESPACE_ID) throw new Error("ALETHEION_NAMESPACE_ID is missing");
// Send one authenticated request to AletheionAGI and decode its JSON response.
// T is the response shape expected by the calling function; in production, generate
// these types from the approved OpenAPI v1 contract.
async function aletheion<T>(path: string, init: RequestInit): Promise<T> {
const response = await fetch(`${ALETHEION_BASE_URL}${path}`, {
...init,
headers: {
// The bearer key determines organization, project and environment authority.
Authorization: `Bearer ${ALETHEION_API_KEY}`,
"Content-Type": "application/json",
// Preserve endpoint-specific headers such as Idempotency-Key.
...init.headers,
},
// Stop waiting after 30 seconds instead of leaving a request open indefinitely.
signal: AbortSignal.timeout(30_000),
});
const body = await response.json();
if (!response.ok) {
// Real applications should also record body.error.correlation_id for support,
// while keeping credentials and memory content out of logs.
throw new Error(`Aletheion ${body.error?.code ?? response.status}`);
}
return body as T;
}
// Store one canonical memory that future queries may retrieve as evidence.
// The returned state is normally "pending"; wait for "indexed" before testing it.
export async function storeMemory(content: string) {
// memory_id identifies this source fact throughout updates, deletion and auditing.
const memoryId = `memory:${crypto.randomUUID()}`;
return aletheion("/v1/memories", {
method: "POST",
// A unique idempotency key makes a retry safe without creating a duplicate write.
// Reuse this same value only when retrying this exact intended request.
headers: { "Idempotency-Key": crypto.randomUUID() },
body: JSON.stringify({
memory_id: memoryId,
// Replace this example with a stable boundary from your own access model.
namespace_id: ALETHEION_NAMESPACE_ID,
// occurred_at is when the source event or fact became true, in RFC 3339 UTC.
occurred_at: new Date().toISOString(),
content,
content_type: "text/plain",
// source_id tells auditors which upstream system supplied the information.
source_id: "support-policy-system",
// Labels restrict which authorized contexts may receive this memory.
authorization_labels: ["support", "approved"],
metadata: { version: "1" },
}),
});
}
// Retrieve authorized evidence for a question. This function does not call an LLM
// and does not generate the final answer; your application invokes its BYOK reader
// only after inspecting the evidence and grounding decision.
export async function findEvidence(question: string) {
return aletheion("/v1/queries", {
method: "POST",
body: JSON.stringify({
// A new query ID lets usage and audit records trace this operation end to end.
query_id: `query:${crypto.randomUUID()}`,
// The query must use a namespace authorized for the current customer context.
namespace_id: ALETHEION_NAMESPACE_ID,
question,
asked_at: new Date().toISOString(),
// Request at most five candidates; policy checks may return fewer or abstain.
top_k: 5,
}),
});
}Install the HTTP client with pip install httpx, then keep this module on the backend.
# aletheion.py
# Keep this module on your backend so the customer API key never reaches a browser.
import os
import uuid
from datetime import datetime, timezone
import httpx
# Permit an explicit staging/local host while defaulting to the production API.
BASE_URL = os.getenv(
"ALETHEION_BASE_URL",
"https://api.aletheionagi.com",
)
# Fail immediately at startup when the provisioned server credential is absent.
API_KEY = os.environ["ALETHEION_API_KEY"]
NAMESPACE_ID = os.environ["ALETHEION_NAMESPACE_ID"]
# Reuse one authenticated client with a bounded timeout.
client = httpx.Client(
base_url=BASE_URL,
headers={"Authorization": f"Bearer {API_KEY}"},
timeout=30.0,
)
def store_memory(content: str) -> dict:
# Idempotency makes an exact network retry safe; memory_id tracks the source fact.
response = client.post(
"/v1/memories",
headers={"Idempotency-Key": str(uuid.uuid4())},
json={
"memory_id": f"memory:{uuid.uuid4()}",
# Replace this with a stable namespace from your authorization model.
"namespace_id": NAMESPACE_ID,
"occurred_at": datetime.now(timezone.utc).isoformat(),
"content": content,
"content_type": "text/plain",
# Identify the upstream source and the contexts allowed to receive it.
"source_id": "support-policy-system",
"authorization_labels": ["support", "approved"],
"metadata": {"version": "1"},
},
)
response.raise_for_status()
# This response is normally pending; wait for indexed before testing retrieval.
return response.json()
def find_evidence(question: str) -> dict:
# Retrieve authorized evidence only. Your BYOK reader remains a separate call.
response = client.post(
"/v1/queries",
json={
"query_id": f"query:{uuid.uuid4()}",
"namespace_id": NAMESPACE_ID,
"question": question,
"asked_at": datetime.now(timezone.utc).isoformat(),
# Ask for at most five candidates; validation can return fewer or abstain.
"top_k": 5,
},
)
response.raise_for_status()
return response.json()04
Follow one controlled request flow.
AletheionAGI checks which company is calling, which namespace it may access, whether each memory is current and whether it can be disclosed. Configure the provider, model and encrypted API key in Reader BYOK. The provider account and token charges remain owned by your company.
05
Store information your system may rely on.
Send the request to the complete production address shown below. A memory should come from a known source and belong to a clear namespace. The unique idempotency key makes retrying a network interruption safe: the same intended write is not stored twice.
curl -X POST "https://api.aletheionagi.com/v1/memories" \
-H "Authorization: Bearer $ALETHEION_API_KEY" \
-H "Idempotency-Key: 01J-example-unique-write" \
-H "Content-Type: application/json" \
-d '{
"memory_id": "policy:refund:v1",
"namespace_id": "support:550e8400-e29b-41d4-a716-446655440000",
"occurred_at": "2026-08-13T12:00:00Z",
"content": "Refunds are available within the approved policy window.",
"content_type": "text/plain",
"source_id": "policy-system:refunds",
"authorization_labels": ["support", "approved"]
}'{
"memory_id": "policy:refund:v1",
"namespace_id": "support:550e8400-e29b-41d4-a716-446655440000",
"state": "pending",
"revision": 1
}What happens next: pending means AletheionAGI accepted the memory but retrieval is still being prepared. Use it only after it becomes indexed. Failed, deleted or revoked memory cannot be disclosed as active evidence.
Wait until the memory is indexed
The production pipeline is asynchronous. Poll GET /v1/memories/{memory_id} before expecting a newly written memory to appear in retrieval.
// The POST returns state "pending". Wait before querying this memory.
async function waitUntilIndexed(memoryId: string) {
for (let attempt = 0; attempt < 30; attempt += 1) {
const memory = await aletheion<{ state: string }>(
`/v1/memories/${encodeURIComponent(memoryId)}`,
{ method: "GET" },
);
if (memory.state === "indexed") return memory;
if (memory.state === "failed") throw new Error("Memory indexing failed");
await new Promise((resolve) => setTimeout(resolve, 1_000));
}
throw new Error("Memory indexing timed out");
}06 · Advanced
Retrieve evidence without calling the reader.
Most integrations should use /v1/ground. Use https://api.aletheionagi.com/v1/queries only when your backend wants the evidence package and will operate its own reader call.
curl -X POST "https://api.aletheionagi.com/v1/queries" \
-H "Authorization: Bearer $ALETHEION_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query_id": "query:01JEXAMPLE",
"namespace_id": "support:550e8400-e29b-41d4-a716-446655440000",
"question": "What is the approved refund policy?",
"asked_at": "2026-08-13T12:05:00Z",
"top_k": 5
}'Important: top_k: 5 asks for at most five candidates. It does not guarantee five results; unauthorized, stale or invalid evidence is removed.
07
Let the decision control delivery.
The grounding action is not a quality score or suggestion. It tells your application what it may do next.
Evidence supports the response. Deliver only the claims actually covered by that evidence.
A known safety or grounding rule failed. Do not send the proposed response.
There is not enough eligible evidence. Ask for clarification or say the system cannot confirm.
Never turn a block or abstention into an ungrounded reader call. A citation attached somewhere in a response cannot justify a different unsupported claim.
07
Usage and billing
One finalized accepted, reduced, rejected or abstained operation consumes one prepaid grounding query. An internal failure reverses the reservation. Because the final reader response is not replayed, reusing a completed query_id returns HTTP 409 idempotency_replay_unavailable and does not consume another unit.
GET /v1/usagePeriod consumption and estimated overageGET /v1/usage/creditsAllowance, available balance and hard-stop state08
Handle structured errors
Branch on error.code, never on the human-readable message. Persist the returned correlation ID for support without logging memory content or secrets.
validation_errorunauthenticatedforbiddenrate_limitedidempotency_replay_unavailablegrounding_rejecteddependency_unavailableinternal_error09
Production checklist
- Use one API key per project and environment.
- Derive organization authority from credentials, never request bodies.
- Use stable namespaces and the minimum necessary labels.
- Generate a new idempotency key for each intended write.
- Configure reader credentials only through the authenticated Reader BYOK page; never expose them in application browser code.
- Honor
blockandabstainwithout fallback guessing. - Record correlation IDs and grounding actions in your audit trail.
- Test cross-tenant isolation before production traffic.