Services
An org can have more than one service for the same scope — for example a local Whisper service and an OpenAI transcription service, both serving `stt`. This endpoint lists them so your client knows which service_ids it can route to.
Why multiple services per scope?
Each service carries its own configuration, limits, and upstream binding. For scopes where that matters — different audio models, different PII thresholds, different language backends — configuring a second service is cleaner than juggling one shared row. Requests without a service_id hit the one flagged as is_default for that scope; requests with a service_id go straight to that service.
Completions route via the model field plus per-model upstream bindings, so service_iddoesn't apply there. Every other scope — STT, PII, language, TTS — accepts service_idand uses the org's default service when omitted.
Model addressing — base + profile
Completion model values use a <base>:<profile> form (for example gpt-4o:chat). The base owns identity and pricing for one upstream model; profiles attach to a base and supply behaviour overrides like a system prompt or default sampling parameters. Calling without a profile suffix resolves to the base directly.
Bases pin a global upstream template — the protocol shape (openai-compatible, anthropic-compatible, …) — not a specific org-scoped upstream. Two bases attached to different templates can share the same underlying upstream model_id: for example openai/gpt-4o on the openai-compatible template and anthropic-bedrock/gpt-4o on a different protocol shape would be two distinct rows with their own pricing. Within a single template, one (template, model_id) pair owns at most one base — every org routing through that template shares it. The portal disambiguates by the operator-chosen name; profiles attached to one base never bleed into the other.
Pricing always resolves through the parent base — see How pricing inherits for the resolution chain.
Per-model overrides
When you attach a profile to a service model, the profile's system prompt, default parameters, processor list, and processor settings become the model's defaults. The Behaviour and Processors tabs each expose an Override toggle per field so you can replace any of those bundles for a specific model.
Every override toggle is bundle replacement, not key-level merge. With Override off the input is disabled and the profile's value is used verbatim. With Override on, the profile's value is removed for this model — you take ownership of the entire bundle and need to fill in every value you want sent. For default_paramsthat means keys you don't set fall back to the upstream provider's defaults, not the profile's; for the processor list it means the template's processors don't run unless you tick them; for processor settings it means the template's settings bundle is dropped. Toggle Override back off to restore inheritance.
The trade-off: bundle replacement is the same predictable rule for every field, and the UI makes it obvious what's active. If you want to add one processor on top of the profile's list, you currently have to override the whole bundle and re-pick the template's steps alongside your additions.
List services
/v1/servicesLists the services the caller can reach. For API tokens, filtered to the scopes the token carries; for portal sessions, returns every service in the org.
Request
scopestring- Optional. Narrow to a single scope (e.g. stt, pii, language).
curl https://api.inferada.com/v1/services?scope=stt \
-H "Authorization: Bearer inf_YOUR_TOKEN"Response · 200
services[].idstring- Service identifier. Pass as service_id on scope-specific endpoints.
services[].scopestring- completions, language, pii, stt or tts.
services[].namestring- Human-readable display name.
services[].activeboolean- Inactive services are filtered out but surface here for visibility.
services[].is_defaultboolean- True for the service that handles scope requests when no service_id is given.
{
"services": [
{
"id": "01J5Z...",
"scope": "stt",
"name": "Speech-to-Text (Local Whisper)",
"active": true,
"is_default": true
},
{
"id": "01J6A...",
"scope": "stt",
"name": "Speech-to-Text (OpenAI)",
"active": true,
"is_default": false
}
]
}Route a request with service_id
Pass service_idalongside the normal request body (or as a form field for multipart endpoints). The gateway validates that the service belongs to your org and matches the endpoint's scope, then routes there instead of the default.
curl https://api.inferada.com/v1/audio/transcriptions \
-H "Authorization: Bearer inf_YOUR_TOKEN" \
-F service_id=01J6A... \
-F file=@speech.mp3Errors: unknown service_id → 404; service_id from another org or with the wrong scope → 403.