The gateway speaks both wire protocols the AI world uses — OpenAI'schat/completions and Anthropic'smessages. Point any existing client at it: PII is masked before egress, the right model is chosen per call, and a signed, chained, offline-verifiable certificate is issued for every completion.
Authentication
Use a developer API key (sk_live_…). Both header styles work, so both official SDKs work unchanged:
Authorization: Bearer sk_live_… — what the OpenAI SDK sends
x-api-key: sk_live_… — what the Anthropic SDK sends
Billing. Every call is metered against the workspace's token balance (charged to the workspace owner) and recorded in the token ledger. An empty balance returns 402 insufficient_quota (OpenAI dialect) / 429 rate_limit_error (Anthropic dialect) before any provider call is made. On-prem installs are licence-based and unmetered — usage is still ledgered for the cockpit.
OpenAI SDK
import OpenAI from 'openai'
// The one changed line: point the official SDK at the gateway.
const client = new OpenAI({
baseURL: 'https://api.pulse-labs.fr/v1', // or http://localhost:3051/v1
apiKey: process.env.PULSE_API_KEY, // sk_live_... developer key
})
const { data, response } = await client.chat.completions
.create({
model: 'pulse-auto',
messages: [{ role: 'user', content: 'Summarise this contract clause…' }],
})
.withResponse()
data.choices[0].message.content // the answer, PII restored
response.headers.get('x-pulse-proof') // certificate id — fetch it, keep it, hand it to an auditor
Anthropic SDK
@anthropic-ai/sdk
import Anthropic from '@anthropic-ai/sdk'
// Same gateway, Anthropic dialect — /v1/messages.
const client = new Anthropic({
baseURL: 'https://api.pulse-labs.fr', // no /v1 — the SDK adds it
apiKey: process.env.PULSE_API_KEY, // sk_live_... developer key
})
const { data, response } = await client.messages
.create({
model: 'pulse-auto',
max_tokens: 1024,
messages: [{ role: 'user', content: 'Summarise this contract clause…' }],
})
.withResponse()
data.content // Anthropic content blocks
response.headers.get('x-pulse-proof') // same proof registry as the OpenAI dialect
Claude Code
Claude Code speaks the Anthropic protocol, so it can run entirely through the gateway — every turn of the agent loop masked, routed, and attested. Environment variables are session-scoped: your normal claude.ai login is untouched, and closing the terminal reverts everything.
# PowerShell — session-scoped: close the terminal and Claude Code
# talks to Anthropic's cloud again. Nothing persistent is changed.
$env:ANTHROPIC_BASE_URL = "https://api.pulse-labs.fr" # or http://localhost:3051
$env:ANTHROPIC_AUTH_TOKEN = "sk_live_..." # AUTH_TOKEN, not API_KEY (see note)
$env:ANTHROPIC_MODEL = "pulse-auto"
$env:ANTHROPIC_SMALL_FAST_MODEL = "pulse-auto"
claude # every turn now flows through the gateway, attested
ANTHROPIC_AUTH_TOKEN, not ANTHROPIC_API_KEY. The Claude Code CLI only accepts Anthropic-issued key formats (sk-ant-…) inANTHROPIC_API_KEY and will show “Not logged in” otherwise.ANTHROPIC_AUTH_TOKEN sends the key as a Bearer header, which the gateway accepts. Set ANTHROPIC_MODEL=pulse-auto so the router decides.
Model addressing — the model field is an address
The model field is the one setting every third-party client exposes — so the gateway reads it as an address that selects which Pulse capability serves the call. Without a Pulse prefix or flag, the gateway stays a faithful passthrough: capabilities are opt-in by address, never imposed.
pulse-auto
Synapse routes each call: cheap model for simple asks, full model for complex work, local for detected-sensitive chat traffic.
pulse-agent
Forces the configured full-quality model. Agent harnesses (tool loops, large system prompts) are detected automatically — this alias just makes it explicit.
pulse-sensitive
Forces local processing (Ollama). The request never leaves the machine, and the certificate proves it.
agent:<slug>
Served BY one of your workspace agents — its system prompt, memory, documents and tools. Slug = agent name, lowercased and dashed («Demo CFO» → agent:demo-cfo).
<base>+cortex
Grounds the call in the workspace knowledge base; the retrieved passages are hashed into the certificate.
Reserved — answers 501 with a pointer to POST /v1/conversations for now.
Addressing in practice
// Same SDK, same one changed line — the model name selects the capability.
// Served by YOUR agent: its system prompt, memory, documents and tools.
await client.chat.completions.create({
model: 'agent:demo-cfo',
messages: [{ role: 'user', content: 'What is our runway looking like?' }],
})
// Grounded in the workspace knowledge base — the retrieved passages are
// hashed into the certificate (level-2 proof: "based on these exact sources").
await client.chat.completions.create({
model: 'pulse-auto+cortex',
messages: [{ role: 'user', content: 'Summarise our onboarding checklist.' }],
})
// Flags compose. The legal agent, forced local — nothing leaves the machine.
await client.chat.completions.create({
model: 'agent:legal+sensitive',
messages: [{ role: 'user', content: 'Review this clause…' }],
})
Your agents show up in model pickers. GET /v1/models lists the aliases and every agent of your workspace as agent:<slug> entries — so in any tool with a model dropdown (Cursor, Continue, n8n…), your own agents appear as selectable models. Zero integration.
Any other model name is accepted and recorded in the certificate; routing still applies. Requested max_tokens above the provider cap are clamped at ingress (GATEWAY_MAX_OUTPUT_TOKENS, default 16000) instead of failing your loop.agent: calls run the persona's own tools server-side and ignore caller-supplied tools/response_format.
The proof certificate
Every completion returns an x-pulse-proof header. Fetch the certificate atGET /v1/proofs/:id. It commits to your request, the redacted egress, and the response via sha256 — it never contains the content itself, so it can be handed to an auditor, a client, or a regulator as-is.
Chained, so deletion is visible. Each certificate embeds the hash of the previous one (chainIndex / prevHash). Silently removing one breaks the chain for every verifier.
Two proof levels. Every call gets a level-1 certificate: pipeline attested (request, masking, model, response). Calls served by an agent or carrying +cortex add level-2: the grounding array commits, by hash, to the exact knowledge passages the answer drew on — “grounded in these exact sources”, verifiable by an auditor.
Verify offline — don't trust the gateway
Verification needs only the certificate and the public key fromGET /v1/gateway/public-key (open endpoint, no auth) — ~15 lines in any language with an Ed25519 implementation:
Offline verification
// Offline verification — no API key, no network trust required.
// Inputs: the certificate JSON + the gateway's public key (GET /v1/gateway/public-key).
import crypto from 'node:crypto'
function canonicalJson(v) {
if (v === null || typeof v !== 'object') return JSON.stringify(v)
if (Array.isArray(v)) return `[${v.map(canonicalJson).join(',')}]`
const e = Object.entries(v).filter(([, x]) => x !== undefined).sort(([a], [b]) => (a < b ? -1 : 1))
return `{${e.map(([k, x]) => `${JSON.stringify(k)}:${canonicalJson(x)}`).join(',')}}`
}
const recomputed = crypto.createHash('sha256').update(canonicalJson(cert.payload), 'utf8').digest('hex')
const authentic =
recomputed === cert.payload_hash &&
crypto.verify(null, Buffer.from(cert.payload_hash, 'utf8'),
crypto.createPublicKey(publicKeyPem), Buffer.from(cert.signature, 'base64'))
Endpoints
POST /v1/chat/completionsOpenAI dialect — streaming, tools, response_format
POST /v1/messagesAnthropic dialect — streaming, tools, system blocks
POST /v1/messages/count_tokensAnthropic token counting (estimate)
GET /v1/modelsModel aliases + your workspace agents as addresses
GET /v1/proofs/:idFetch a certificate (scoped to your workspace)
GET /v1/proofs/:id/verifyServer-side signature + chain check
GET /v1/gateway/public-keyEd25519 public key — no auth, for offline verification
How it relates to the other engines. Behind the gateway, every call runs the full Synapse pipeline — PII Shield, model routing, cost ledger. Connect Pulse Cortex and certificates upgrade from “pipeline attested” to “grounded in these exact sources”.