Documentation

Agentic Gateway en 10 minutes

Du premier curl à la première clé virtuelle émise pour un client.

1. Démarrage rapide

Lancez la stack de développement (gateway + Postgres) puis vérifiez la santé du service.

shell
./scripts/run-stack.sh up       # gateway :4101, Postgres :54100
curl localhost:4101/health      # {"status":"ok"}

Ouvrez ensuite la console opérateur et connectez-vous avec la master key (dev-master-key en dev).

2. Deux types de clés, deux mondes

Master key

Clé de l'opérateur. Donne accès à /admin/* : tenants, clés, guardrails, usage. Une seule par déploiement, saisie une fois dans la console.

Virtual key

Clé d'un client ou d'un agent, format sk-agentic-…. Donne accès à /v1/*. Hachée côté serveur, affichée en clair une seule fois à l'émission.

Les clés fournisseurs (OpenAI, Anthropic…) ne sortent jamais du gateway : ni l'API, ni la console ne les exposent.

3. Référence API v1 (virtual key)

POST /v1/chat/completions
Authorization: Bearer sk-agentic-…
Content-Type: application/json

{ "model": "openai/gpt-4o-mini",
  "messages": [{ "role": "user", "content": "Bonjour" }],
  "stream": false }

→ 200 { "id": "chatcmpl-…", "object": "chat.completion",
        "choices": [{ "message": { "role": "assistant", "content": "…" }, "finish_reason": "stop" }],
        "usage": { "prompt_tokens": 12, "completion_tokens": 8, "total_tokens": 20 } }

Avec "stream": true, la réponse est un flux SSE de chunks chat.completion.chunk terminé par data: [DONE].

POST /v1/embeddings · GET /v1/models · GET /health
POST /v1/embeddings   { "model": "text-embedding-3-small", "input": "hello" }
GET  /v1/models       → { "object": "list", "data": [{ "id": "openai/gpt-4o", "owned_by": "openai" }, …] }
GET  /health          → { "status": "ok" }   (sans clé)

4. API admin (master key)

MéthodeRouteCorpsRéponse
GET/admin/health—{"db":"ok","providers_configured":1,"version":"0.6.0"}
GET · POST/admin/tenants{"id":"acme","name":"Acme Corp"}liste enrichie (nom, clés actives, coût) · création, 409 si existe
POST/admin/tenants/rename{"tenant_id","name"}renommage
DELETE/admin/tenants/remove?tenant_id=—suppression douce, 409 sur default
GET · POST/admin/keys{"tenant_id","label","budget_usd"}liste avec dépense · émission, clé en clair une seule fois
POST/admin/keys/patch · /admin/keys/revoke{"key_id","label","budget_usd"}modification · révocation
GET · POST · DELETE/admin/guardrails{"tenant_id","blocked_patterns","max_input_chars"}lecture · écriture · réinitialisation
GET · POST/admin/providers{"id","api_key","base_url","extra"}liste (jamais la clé) · ajout ou remplacement
POST · DELETE/admin/providers/test · /remove?id=—test de la clé · retrait
GET/admin/providers/catalog · /admin/models/catalog—providers connus · modèles, prix et capacités
GET/admin/usage[/timeseries|/breakdown|/events]—totaux, série par jour, répartition par modèle, clé ou provider, journal

Les erreurs suivent le format OpenAI : {"error":{"message":"…","type":"auth_error"}}, 401 si la clé est absente, invalide ou révoquée.

5. Utiliser le SDK OpenAI

TypeScript
import OpenAI from "openai";
const client = new OpenAI({ baseURL: "http://localhost:4101/v1", apiKey: process.env.AGENTIC_KEY });

const stream = await client.chat.completions.create({
  model: "anthropic/claude-sonnet-4", stream: true,
  messages: [{ role: "user", content: "Explique SSE en une phrase." }],
});
for await (const chunk of stream) process.stdout.write(chunk.choices[0]?.delta?.content ?? "");

6. Auto-hébergement

docker-compose.prod.yml (extrait)
services:
  gateway:
    image: ghcr.io/grantity/agentic-gateway:latest
    environment:
      GATEWAY_MASTER_KEY: ${GATEWAY_MASTER_KEY}
      DATABASE_URL: postgres://gateway:gateway@db:5432/gateway
      OPENAI_API_KEY: ${OPENAI_API_KEY}
      ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY}
    ports: ["4101:4000"]
  db:
    image: postgres:16

La console (ce site, dossier website/) se déploie à part et relaie les appels vers le gateway via la variable GATEWAY_URL.