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.

Evidence-firstYour reader stays yoursAccounts stay isolated

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.

Do this when information changes

1. Teach the notebook

Send trusted policies, product facts and approved information to POST /v1/memories. AletheionAGI stores and indexes them.

Trusted information/v1/memoriesIndexed memory
Good things to put in a memory

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.

Do this for every user question

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.

User input/v1/groundgrounded_answer

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.

AletheionAGI

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
Your application

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
Memory

A fact, policy or event your company deliberately stores.

Namespace

A boundary that groups data that may be retrieved together.

Reader

Your LLM or model that produces the final response.

Grounding query

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.

1Activate the workspace

An organization membership is established first. Activation then creates the default project plus Sandbox and Production; an owner issues the server key.

2Send approved memory

Your backend sends facts, policies or events with their source and access labels.

3Ask for evidence

Your backend sends the question and namespace. AletheionAGI returns eligible evidence.

4Generate safely

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.

Correct

Store ALETHEION_API_KEY in your backend platform's secret manager. Use a different key for staging and production.

Unsafe

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.

Control plane

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
Application plane

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.

Organization

The legal/customer account that owns usage and billing.

Project

An application or team requiring independent keys and lifecycle.

Environment

The automatically provisioned Sandbox or Production stage.

Namespace

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

Register known boundaries

  1. Open Dashboard → Namespaces.
  2. Select the project and environment.
  3. Enter a stable <kind>:<uuid> identifier and human-readable name.
  4. Create a key without namespace:provision.

Unknown namespaces fail closed. Use this for a bounded list of departments, assistants, knowledge bases or regulated datasets.

Delegated mode

Create application identities on demand

  1. Open Dashboard → API keys.
  2. Select only the necessary memory/query permissions.
  3. Define prefixes from your own domain and enable namespace:provision.
  4. 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 query

Least 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-446655440000
TypeScript · Node.js 20+

Uses 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,
    }),
  });
}
Python 3.11+

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.

Your backendsends questionAletheionAGIretrieves evidenceYour BYOK readerreturns outputBridge decision

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"]
  }'
Expected first response · HTTP 202
{
  "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.

deliver

Evidence supports the response. Deliver only the claims actually covered by that evidence.

block

A known safety or grounding rule failed. Do not send the proposed response.

abstain

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 state

08

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_error

09

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 block and abstain without fallback guessing.
  • Record correlation IDs and grounding actions in your audit trail.
  • Test cross-tenant isolation before production traffic.