Skip to content

Model addressing

The model field is an address: prefixes pick who answers (Synapse, a full model, a local model, one of your agents) and +flags add or remove capabilities.

Every AI client lets you change one thing: the model name. Subsidia uses that single field as an address. The text before the first + selects which capability serves the call; each +flag after it adds or removes something. Your agents, your knowledge base and local-only processing therefore become reachable from tools that know nothing about Subsidia: Cursor, Continue, n8n, LangChain, Claude Code, or a script you wrote against the OpenAI SDK.

The address is parsed identically on POST /v1/chat/completions and POST /v1/messages (see Gateway), and the original string is recorded verbatim in the proof certificate.

Grammar

<base>[+flag][+flag]...

base  = pulse-auto | pulse-agent | pulse-sensitive | agent:<slug> | debate:<slug> | any other string
flag  = cortex | sensitive | agent | nocortex | noknowledge | nomemory

Parsing rules, all taken from the parser:

  • The string is split on +. The first part is the base, the rest are flags.
  • Whitespace around each part is trimmed. Flags are case-insensitive (+Cortex works); the base is case-sensitive (Pulse-Auto is just an unknown name, so a passthrough).
  • Flag order does not matter and flags compose freely.
  • An unknown flag is silently ignored, with no error. Check spelling: pulse-auto+cortx is a plain pulse-auto call.
  • A base that starts with agent: or debate: is followed by a slug. The slug is normalised the same way agent names are: accents removed, lowercased, every run of non-alphanumeric characters turned into one dash, edge dashes trimmed. agent:Demo CFO and agent:demo-cfo are the same address.

Prefixes

BaseWho answersNotes
pulse-autoSynapse routes the call by task complexity and sensitivity.The default, and what any unknown or missing model name behaves like. See Synapse.
pulse-agentThe configured full-quality model, always.Marks the call as agentic so it is never handed to the small model. For harnesses and tool loops. The Gateway also detects agentic traffic on its own (see below).
pulse-sensitiveLocal processing, always.Same as pulse-auto+sensitive. Where a local model exists the request never leaves the machine and the certificate shows the provider. See the caveat in Sensitive.
agent:<slug>One of your workspace agents.Its prompt, memory, documents and tools. Unknown slug is a 404 model_not_found. See Agents.
debate:<slug>Reserved.Parsed but not served: 501 address_not_supported (OpenAI dialect) or 501 invalid_request_error (Anthropic dialect). Use the Conversations API.
Any other namePassthrough, routed like pulse-auto.gpt-4o, claude-sonnet-4-6, my-model. Accepted, recorded in the certificate as request.model, and routed by Synapse regardless of the name.

Flags

FlagApplies toEffect
+cortexNon-agent addressesRetrieves the five most relevant passages of your knowledge base for the last user message, adds them to the prompt as cited context, and commits their hashes to the certificate (grounding). If nothing matches, the call proceeds ungrounded.
+sensitiveNon-agent addressesForces local routing. Equivalent to the pulse-sensitive base, and composable with any other base.
+agentNon-agent addressesForces the full-quality model. Equivalent to the pulse-agent base.
+nocortexagent: onlyThe agent answers from its persona alone, without searching the knowledge base. Recorded in the certificate as address.knowledge: false (OpenAI dialect).
+noknowledgeagent: onlyAlias of +nocortex.
+nomemoryagent: onlyThe agent neither recalls nor writes persistent memory. The call inherits nothing and leaves nothing behind. Recorded as address.memory: false (OpenAI dialect).

The negative flags exist because an address that could only add capability gave callers running an isolated experiment no way to stop an agent from inheriting, and leaving, state across calls. agent:cfo+nocortex+nomemory is a clean-room run of the persona.

Which flags are read where. The parser accepts every flag on every address, but the Gateway only acts on the ones that make sense for the kind of call. +nocortex, +noknowledge and +nomemory are used by agent: calls only. For +cortex, an agent: call already grounds itself in the agent's own knowledge unless you add +nocortex, so the flag adds nothing there. For +sensitive on an agent: address, the Gateway does not pass the flag to the agent pipeline today; use pulse-sensitive when local processing is a hard requirement.

Sensitive

Composition

AddressParsed as
pulse-autoSynapse routing, nothing added.
gpt-4oPassthrough, Synapse routing, nothing added. The name is only recorded.
gpt-4o+cortexPassthrough plus knowledge grounding.
pulse-auto+cortexSynapse routing plus knowledge grounding.
pulse-agent+cortexFull model, always, grounded in your knowledge base.
pulse-sensitive+cortexLocal model, grounded. The passages never leave the machine either.
pulse-auto+sensitive+cortexSame as the line above, in a different spelling. Flag order is irrelevant.
agent:demo-cfoThe agent, with its knowledge base and memory on.
agent:demo-cfo+nocortexThe agent, persona only.
agent:demo-cfo+nomemoryThe agent, with knowledge, no memory read or written.
agent:demo-cfo+nocortex+nomemoryThe agent as a stateless persona.
agent:Demo CFOSame as agent:demo-cfo (slug normalised).
debate:boardReserved. 501.
pulse-auto+cortxTypo in a flag: ignored, so a plain pulse-auto.

Examples

The request body is identical in every case; only model changes.

Ground a call in your knowledge base
curl https://api.subsidia.protypa.fr/v1/chat/completions \
-H "Authorization: Bearer $SUBSIDIA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "pulse-auto+cortex",
"messages": [{"role": "user", "content": "What notice period does the Martin lease require?"}]
}'
Talk to an agent, then continue the same thread
# First turn: read the conversation id from the response headers
curl -i https://api.subsidia.protypa.fr/v1/chat/completions \
-H "Authorization: Bearer $SUBSIDIA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"agent:demo-cfo","messages":[{"role":"user","content":"Summarise our cash position."}]}'
# Second turn: send it back to continue the same persona-side conversation
curl https://api.subsidia.protypa.fr/v1/chat/completions \
-H "Authorization: Bearer $SUBSIDIA_API_KEY" \
-H "x-pulse-conversation: $CONVERSATION_ID" \
-H "Content-Type: application/json" \
-d '{"model":"agent:demo-cfo","messages":[{"role":"user","content":"And next quarter?"}]}'
Other addresses, same call
# Hard requirement: stay on a local model, grounded in the knowledge base
client.chat.completions.create(model="pulse-sensitive+cortex", messages=msgs)
# Always the full model, for an agent harness or a long tool loop
client.chat.completions.create(model="pulse-agent", messages=msgs)
# An agent with no memory and no knowledge base: a reproducible bench
client.chat.completions.create(model="agent:demo-cfo+nocortex+nomemory", messages=msgs)
# A name your tool insists on: still masked, routed, metered and signed
client.chat.completions.create(model="gpt-4o", messages=msgs)
  1. 1
    Pick the base

    Do you need a specific agent (agent:<slug>), a guaranteed-local call (pulse-sensitive), a guaranteed-full model (pulse-agent), or simply the sensible default (pulse-auto)?

  2. 2
    Add flags only for what you need

    +cortex when the answer must come from your documents. +nocortex or +nomemory on an agent when you want an isolated, repeatable run.

  3. 3
    Check what happened

    Read x-pulse-provider and the pulse block of the response, or fetch the certificate: it records your raw address, the parsed kind, the provider that answered and the grounding hashes.

Where the address shows up in a certificate

payload.request.model is the exact string you sent. payload.address records what was parsed:

  • address.kind: auto or agent.
  • address.agent: the agent slug for plain gateway calls. For agent: calls the certificate is signed by the agent pipeline itself, which records the agent identifier it holds internally rather than the slug, so match certificates to agents through the response's pulse.agent field or your own bookkeeping, not by string comparison with the slug.
  • address.cortex: true when +cortex was on a non-agent call.
  • address.knowledge / address.memory: false only when +nocortex / +nomemory switched them off on the OpenAI dialect, so an auditor can see that an answer ran without the knowledge base or without memory.
  • grounding: one entry per passage used, with source name, chunk id, page and SHA-256 of the text.

The Anthropic dialect records kind, agent and cortex only.

Discover addresses with GET /v1/models

GET/v1/models

List the aliases and your workspace agents as addresses.

API key (Bearer or x-api-key)engine

The listing is the discovery surface of the addressing scheme. It always contains pulse-auto, pulse-sensitive and pulse-agent, then the full model currently configured on the installation (for clients that insist on a real model id), then one agent:<slug> entry per agent visible to the key's workspace, oldest agent first. Because model pickers are filled from this route, your own agents appear in the dropdown of Cursor, Continue or n8n with no integration work.

The flags are not listed: they are suffixes you append to any entry.

Request examples

curl https://api.subsidia.protypa.fr/v1/models \
-H "Authorization: Bearer $SUBSIDIA_API_KEY"

Responses

An OpenAI-style list. Gateway aliases are owned by pulse-gateway, agents by pulse-agents.

Example response
{
"object": "list",
"data": [
{ "id": "pulse-auto", "object": "model", "created": 1790000000, "owned_by": "pulse-gateway" },
{ "id": "pulse-sensitive", "object": "model", "created": 1790000000, "owned_by": "pulse-gateway" },
{ "id": "pulse-agent", "object": "model", "created": 1790000000, "owned_by": "pulse-gateway" },
{ "id": "gpt-4o", "object": "model", "created": 1790000000, "owned_by": "pulse-gateway" },
{ "id": "agent:demo-cfo", "object": "model", "created": 1790000000, "owned_by": "pulse-agents" }
]
}

Errors

  • 401No key, wrong key, revoked or expired key.
  • 403scope_deniedThe key does not carry the engine scope.

Notes

The entry after the three aliases is whatever full model the installation is configured with; its id changes when an administrator changes the provider. Do not hard-code it.

Errors specific to addressing

StatusCodeCauseWhat to do
404model_not_found (OpenAI) or not_found_error (Anthropic)No agent in the key's workspace has that slug.Call GET /v1/models and copy the id. Renaming an agent changes its slug.
501address_not_supported (OpenAI) or invalid_request_error (Anthropic)A debate:<slug> address.Use the Conversations API.
404conversation_not_foundThe x-pulse-conversation header names a conversation that does not exist in this workspace.Omit the header to start a new conversation.

Frequently asked

My tool only lets me pick from a fixed list of model names. Can I still use Subsidia?

If the list is editable or the tool fetches it from GET /v1/models, yes. If it is truly fixed, any real model name works as a passthrough (masked, routed, metered, signed), but you lose the capabilities that need an address: agents, +cortex, pulse-sensitive.

Does an unknown model name cause an error?

No. It is accepted, recorded in the certificate, and routed exactly like pulse-auto. The name does not choose the provider or the model, Synapse does. Only the agent: and debate: prefixes can fail.

Can I combine pulse-sensitive with an agent?

Not in one address: the base is either a pulse-* alias or agent:<slug>. agent:<slug>+sensitive parses, but the Gateway does not forward the flag to the agent pipeline today. If an agent must work on data that stays local, restrict the installation's providers instead (see Synapse).

Why did +cortex not change my answer?

Retrieval found no passage for the last user message, so the call ran ungrounded and the certificate has no grounding. The flag also requires a workspace on the key; and on agent: addresses it is redundant, because agents search their knowledge by default. See Querying knowledge to test what your question retrieves.

Is the address case-sensitive?

The base is, the flags are not. Write pulse-auto, not Pulse-Auto. The agent slug is normalised, so agent:Demo CFO finds demo-cfo.

Can I use the + syntax inside a SDK that rejects model names with a plus sign?

A few UIs validate model ids against a pattern. Add the flagged name to the tool's custom models list, or fetch it from your own code. The plus sign is the only separator, there is no alternative spelling.

Related