Skip to main content
chat.pinaivu.ai is the end-user chat product. Unlike the gateway, end users never hold an API key — they authenticate by signing each request with a delegate Ed25519 key (derived from their wallet via the MemWal client SDK). chat-relayer itself is a second Nautilus-pattern Nitro Enclave, and holds the shared gateway/coordinator credential on the user’s behalf.
chat.pinaivu.ai → chat-relayer (Nitro Enclave) → coordinator → node (libp2p)

Authentication

No API key. Every request must carry delegate_pubkey_hex and signature_hex — an Ed25519 signature over the request’s canonical bytes. See chat-relayer authentication for the exact byte format, common client bugs, and a worked example — getting this wrong is the most common integration failure against this endpoint.

POST /v1/chat

Request:
{
  "messages": [{ "role": "user", "content": "..." }],
  "model": "gemma4-e4b-128k:latest",
  "session_id": "<uuid, optional — omit for a new session>",
  "session_key": "<base64, optional — omit on first turn>",
  "owner_address": "<user's Sui address>",
  "namespace": "default",
  "delegate_pubkey_hex": "<64 hex chars>",
  "signature_hex": "<128 hex chars — Ed25519 sig over the canonical bytes>"
}
Response:
{
  "content": "the model's reply",
  "session_id": "uuid — persist for the next turn",
  "session_key": "base64 — persist and resend on the next turn of this session",
  "request_id": "uuid",
  "recalled_facts": ["facts pulled from this owner's long-term memory, if any"],
  "latency_ms": 2465
}
recalled_facts is informational — surface it in the UI for a “remembered from earlier” affordance if you like, but it’s already baked into content.

Two memory layers, both automatic

Nothing extra to send for either — see Memory layers for the full mechanics:
  • Cross-session — chat-relayer embeds the user’s message, recalls relevant facts from this owner_address’s history (scoped per owner — other users’ facts never leak in), and injects them into the prompt. Every turn is analyzed in the background and may add new facts.
  • Intra-session — as long as the client resends the same session_id and session_key, the serving node reconstructs the verbatim recent turns of that specific conversation, even if a different node served the previous turn. Omit session_id to start a fresh one (e.g. a new tab); reuse it to continue.
The cross-session layer’s per-owner encryption key is derived from a relayer-held secret today, not a user-wallet-derived one — see the honest caveat on the memory layers page before treating this as real wallet-gated access control.

Other routes (no auth required)

RoutePurpose
GET /healthLiveness
GET /enclave_healthchat-relayer’s own pubkey + uptime
GET /get_attestationRaw NSM attestation document

What a chat client must persist

Value
Identitydelegate keypair (from the user’s wallet)
Per-sessionsession_id, session_key
Per-accountowner_address, namespace
A chat client never persists or sees a node’s address, a dispatch token, or anything node-specific — that’s fully internal to the coordinator and chat-relayer.

Auth scheme walkthrough

Canonical byte format, a reference signing script, and a real worked request/response pair