DOCS / GETTING STARTED / QUICK START

Quick Start

This walks through a complete local setup: pepper generation, database migration, seeding a management key and a test application, running both apps, and making your first chat completion.

Generate the API key pepper

Every Lattice API key is stored as a hash, never in plaintext. The hash is keyed by a server-side secret called the pepper. Generate one:

bash
Authorization: Bearer lattice_sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

This prints a line like API_KEY_PEPPER=Xk3n.... Paste it into apps/gateway/.env. It must be at least 32 characters — losing it invalidates every key ever issued, which is the intended failure mode for a stolen database dump. See Security for why.

Configure provider credentials

Still in apps/gateway/.env, set credentials for at least one provider so the shipped model registry (gpt-4o, claude-sonnet, gemini-pro) has somewhere to route:

bash
type ProviderAdapter = {
  id: ProviderId;
  createChatCompletion(
    request: ChatCompletionRequest,
    ctx: ProviderRequestContext,
  ): Promise<ChatCompletionResponse>;
  streamChatCompletion(
    request: ChatCompletionRequest,
    ctx: ProviderRequestContext,
  ): AsyncGenerator<ChatCompletionChunk, void, void>;
};

type ProviderRequestContext = {
  apiKey?: string;
  providerModel: string;
  signal: AbortSignal;
};

A provider only needs a key if a registry entry references it. Self-hosted providers (OLLAMA_BASE_URL, VLLM_BASE_URL) don't require a key at all — see Providers.

Configure the database

Fill in DB_HOST, DB_PORT, DB_USER, DB_PASSWORD, DB_SSL, DB_DATABASE in apps/gateway/.env for a Postgres instance you control, then run migrations:

bash
{
  "id": "chatcmpl-...",
  "object": "chat.completion",
  "created": 1755878400,
  "model": "gpt-4o",
  "choices": [
    {
      "index": 0,
      "message": { "role": "assistant", "content": "..." },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 42,
    "completion_tokens": 118,
    "total_tokens": 160
  }
}

Seed a management key

The dashboard needs a management API key to administer the gateway. Mint one:

bash
data: {"id":"chatcmpl-...","object":"chat.completion.chunk","created":1755878400,"model":"gpt-4o","choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null}]}

data: {"id":"chatcmpl-...","object":"chat.completion.chunk","created":1755878400,"model":"gpt-4o","choices":[{"index":0,"delta":{"content":"Sure"},"finish_reason":null}]}

data: {"id":"chatcmpl-...","object":"chat.completion.chunk","created":1755878400,"model":"gpt-4o","choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"usage":{"prompt_tokens":42,"completion_tokens":118,"total_tokens":160}}

data: [DONE]

This prints the key exactly once:

text
type ChatCompletionChunk = {
  id: string;
  object: 'chat.completion.chunk';
  created: number;
  model: string;
  choices: [
    {
      index: number;
      delta: { role?: 'assistant'; content?: string };
      finish_reason: 'stop' | 'length' | 'content_filter' | null;
    },
  ];
  usage?: { prompt_tokens: number; completion_tokens: number; total_tokens: number } | null;
};

Copy that key into apps/dashboard/.env as LATTICE_MANAGEMENT_API_KEY.

Run the gateway

bash
import OpenAI from 'openai';

const client = new OpenAI({
  apiKey: process.env.LATTICE_API_KEY,
  baseURL: 'https://gateway.internal/v1',
});

The gateway listens on :3001 by default (PORT in .env).

Set up the dashboard

In a second terminal:

bash
cd apps/dashboard
cp .env.example .env

Fill in:

bash
NUXT_BETTER_AUTH_SECRET=<openssl rand -base64 32>
LATTICE_GATEWAY_URL=http://localhost:3001
LATTICE_MANAGEMENT_API_KEY=<the key from step 5>
DB_HOST=... DB_PORT=... DB_USER=... DB_PASSWORD=... DB_SSL=... DB_DATABASE=...

The dashboard's database only stores its own admin sessions (better-auth) — it can be a separate Postgres database from the gateway's. Then migrate and run:

bash
bun run db:migrate
bun run dev

The dashboard listens on :3000 by default. Open it, sign up an admin account, and sign in.

Create a test application and make a request

From apps/gateway, seed an application with its own API key (independent of the dashboard, useful for scripting):

bash
bun run seed "My Test App"
text
Application created: 8f1c... (My Test App)
API key (shown once, store it now): lattice_sk_...

Call the gateway directly:

bash
curl http://localhost:3001/v1/chat/completions \
  -H "authorization: Bearer lattice_sk_..." \
  -H "content-type: application/json" \
  -d '{
    "model": "gpt-4o",
    "messages": [{ "role": "user", "content": "Say hello in five words." }]
  }'

A 200 with a chat.completion body means the gateway authenticated the key, routed to OpenAI, and logged the request. See Chat Completions for the full request/response reference, including streaming.

What you just set up

POST /v1/chat/completions verify API key, check quota + rate limit resolve model → candidate chain forward request 200 + completion response usage + request log (fire-and-forget) Application Gateway Primary provider Postgres

Next, read Architecture to understand routing and failover, or Management API to provision real applications.

LATTICE — INTERNAL AI INFRASTRUCTURE
GITHUB © 2026