Change one line. Every AI call becomes provable.
Point the SDK you already use at the Subsidia Gateway. It speaks both the OpenAI and Anthropic wire formats, so your code stays as it is while traffic runs through the engine and comes back with a proof.
In an editor, an OpenAI SDK client changes a single line: baseURL goes from api.openai.com to api.subsidia.protypa.fr, and the key becomes SUBSIDIA_API_KEY. The model becomes the address pulse-auto+cortex and the message holds a made-up name, email and IBAN. The answer comes back as HTTP 200 with the headers x-pulse-proof, x-pulse-provider and x-pulse-pii-masked (2 values masked before leaving for the provider), then the answer text. A proof certificate appears: id, model route, chain position and previous hash, document hash and Ed25519 signature. It is verified offline: hash recomputed, signature valid, chain link in place. One line changed. Every call proven.
Your team is already sending prompts to third-party clouds.
Your AI traffic is already leaking
Prompts carry customer names, addresses and production data, with no record of what left or when.
Nothing is provable after the fact
An application log you wrote yourself is not evidence a customer or an auditor can rely on.
Rewriting applications is off the table
A fix that means touching application code dies in the backlog. The one integration budget that always exists is a config line.
A pipeline you don't write, on traffic you don't rewrite.
- 1
PII shield
Emails, IBANs, phone numbers (and names, in strict mode) are swapped for consistent tokens before anything goes to an external provider, then restored in the response.
- 2
Model routing
A cheap model for simple requests, a heavier one for complex work. No provider hard-coded.
- 3
Metering
Usage is counted against your workspace, and a key can carry its own monthly ceiling.
- 4
Signed certificate
Every response carries an Ed25519 attestation, hash-chained: the request, what actually left (masked), the sources used.
The model field is an address.
With no Subsidia prefix the Gateway is a faithful passthrough. Capabilities switch on only when you write them into the address, and they compose.
"pulse-auto"routed per call by complexity"pulse-sensitive"forced onto a local model; the certificate proves it"agent:cfo"the workspace agent answers (memory, documents, tools)"pulse-auto+cortex"grounded in the knowledge base
GET /v1/models lists the models and agent addresses of your workspace.
Four ways to swap the URL.
The key is read from SUBSIDIA_API_KEY. The Anthropic SDK takes the bare host and appends /v1/messages itself.
import OpenAI from "openai"
const client = new OpenAI({
baseURL: "https://api.subsidia.protypa.fr/v1",
apiKey: process.env.SUBSIDIA_API_KEY,
})
const { data, response } = await client.chat.completions
.create({
model: "pulse-auto",
messages: [{ role: "user", content: "Summarise this clause." }],
})
.withResponse()
console.log(response.headers.get("x-pulse-proof"))import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.subsidia.protypa.fr/v1",
api_key=os.environ["SUBSIDIA_API_KEY"],
)
raw = client.chat.completions.with_raw_response.create(
model="pulse-auto",
messages=[{"role": "user", "content": "Summarise this clause."}],
)
print(raw.headers.get("x-pulse-proof"))import Anthropic from "@anthropic-ai/sdk"
const client = new Anthropic({
baseURL: "https://api.subsidia.protypa.fr", // host only: the SDK adds /v1/messages
apiKey: process.env.SUBSIDIA_API_KEY,
})
const { data, response } = await client.messages
.create({
model: "pulse-auto",
max_tokens: 1024,
messages: [{ role: "user", content: "Summarise this clause." }],
})
.withResponse()
console.log(response.headers.get("x-pulse-proof"))curl -i https://api.subsidia.protypa.fr/v1/chat/completions \
-H "Authorization: Bearer $SUBSIDIA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "pulse-auto",
"messages": [{"role": "user", "content": "Summarise this clause."}]
}'
# x-pulse-proof: pf_… x-pulse-pii-masked: 2The proof id comes back in the x-pulse-proof header; x-pulse-pii-masked counts the values that were masked.
What an API key opens.
The engine, directly
POST /v1/ai/complete for a direct call, POST /v1/chat/completions and POST /v1/messages for the OpenAI and Anthropic dialects.
Cortex and Light
POST /v1/knowledge/query to query the knowledge base, POST /v1/knowledge-sources to feed it, POST /light/ask for a sourced answer or an honest refusal.
Reflex automations
GET and POST /engine/flows. Anything outbound still waits for human approval (GET /engine/approvals): a key cannot approve itself.
Have any text checked, wherever it came from.
Send a text and the passages it relies on (what your own retrieval returned, or Cortex collections). Each claim gets a verdict: verified, unsupported, contradicted or unverifiable. No model is called, so the result recomputes identically, and the report is signed in the same chain as Gateway certificates.
A check counts as one control, tracked apart from questions. Controls are counted and shown separately; pricing is not set yet.
curl -X POST https://api.subsidia.protypa.fr/v1/verify \
-H "Authorization: Bearer $SUBSIDIA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"text": "Le loyer mensuel est de 1 250 €. Le préavis est de 30 jours.",
"passages": [{
"source": "Bail commercial.pdf", "page": 3,
"content": "Le loyer mensuel est de 1 250 €. Le préavis est de 90 jours."
}]
}'POST /v1/verifycheck a text, signed report returnedGET /v1/verifylist reportsGET /v1/verify/usagethis month's controlsGET /v1/verify/:idread a report backGET /v1/verify/:id/certificateits certificateGET /v1/verify/:id/exportthe report export
The AI usage register, readable by your tools.
The register answers the five mentions of the EU AI Act. Page through it, summarise it, or export it: the export is a signed archive (CSV, JSON, attestation) that also commits to the filters, so a partial extract cannot pass as exhaustive.
GET /v1/registrethe rows, paginatedGET /v1/registre/summarysummary for the filtersGET /v1/registre/exportsigned export (zip)
The register is part of the Cabinet plan; any other plan gets a 402 PLAN_UPGRADE_REQUIRED.
Proof you can show a third party.
Every Gateway response carries a proof id. Fetch the certificate, have it checked, or verify it yourself against the open public key.
GET /v1/proofs/:idthe certificateGET /v1/proofs/:id/verifysignature and chain checkGET /v1/gateway/public-keysigning public key (PEM), no authentication
A key can only do what you give it.
As soon as a key carries a capability scope it becomes strict: only the families it names are reachable. Add readonly so it cannot change anything.
engine/v1/chat/completions, /v1/messages, /v1/models, /v1/ai/*, /v1/proofs, /v1/gateway/*knowledge/v1/knowledge*reflex/engine/* (flows, approvals)light/light/*webhooks/v1/webhooks*partner/partner/* (integrators)proof/v1/verify*, /v1/registre*readonlyread-only; POSTs that only read (chat, messages, verify, knowledge/query…) still work
Older keys that only carry module names stay unrestricted. You create a key after signing in, under Console, Gateway.
Anything that speaks OpenAI or Anthropic speaks Subsidia.
Claude Code can run entirely through the Gateway: every turn of the agent loop is masked, routed and attested. Frameworks and automation tools plug in through their standard base-URL setting.
A cloud proxy can promise. Inside your walls, it can prove.
Self-host all of it
The Gateway runs as a standalone service on your own infrastructure. It is the same one that powers Subsidia's cloud, hosted in France.
Your keys, your register
Each install generates its own Ed25519 signing pair. Nobody can forge or alter a certificate for your traffic.
Local models included
With pulse-sensitive the data stays on the machine, and the certificate establishes it technically, not just by contract.
The full reference lives on the developer portal.
From key to first certificate.
Create an account, open Console, Gateway to generate a key, then try it without writing any code.
After sign-up, head to Console, Gateway.
