curl --request GET \
--url https://{host}/api/llm-gateway/admin/providers \
--header 'Authorization: Bearer <token>'import requests
url = "https://{host}/api/llm-gateway/admin/providers"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://{host}/api/llm-gateway/admin/providers', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://{host}/api/llm-gateway/admin/providers",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://{host}/api/llm-gateway/admin/providers"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://{host}/api/llm-gateway/admin/providers")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://{host}/api/llm-gateway/admin/providers")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body[
{
"auth_type": "<string>",
"base_url": "<string>",
"billing_mode": "per_token",
"created_at": "2023-11-07T05:31:56Z",
"enabled": true,
"enforce_health_check": true,
"health_status": "<string>",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"model_provider": "<string>",
"model_sync_mode": "off",
"name": "<string>",
"org_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"secret_path": "<string>",
"settings": "<unknown>",
"updated_at": "2023-11-07T05:31:56Z",
"created_by_email": "<string>",
"created_by_name": "<string>",
"created_by_user_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"last_change_note": "<string>",
"last_modified_at": "2023-11-07T05:31:56Z",
"last_modified_by_email": "<string>",
"last_modified_by_name": "<string>",
"last_modified_by_user_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"billing_note": "<string>",
"billing_reason": "subscription",
"catalog_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"catalog_slug": "<string>",
"connection_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"health_checked_at": "2023-11-07T05:31:56Z",
"health_detail": "<string>",
"request_timeout_secs": 123,
"stream_idle_timeout_secs": 123
}
]List the organization's providers
curl --request GET \
--url https://{host}/api/llm-gateway/admin/providers \
--header 'Authorization: Bearer <token>'import requests
url = "https://{host}/api/llm-gateway/admin/providers"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://{host}/api/llm-gateway/admin/providers', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://{host}/api/llm-gateway/admin/providers",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://{host}/api/llm-gateway/admin/providers"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://{host}/api/llm-gateway/admin/providers")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://{host}/api/llm-gateway/admin/providers")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body[
{
"auth_type": "<string>",
"base_url": "<string>",
"billing_mode": "per_token",
"created_at": "2023-11-07T05:31:56Z",
"enabled": true,
"enforce_health_check": true,
"health_status": "<string>",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"model_provider": "<string>",
"model_sync_mode": "off",
"name": "<string>",
"org_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"secret_path": "<string>",
"settings": "<unknown>",
"updated_at": "2023-11-07T05:31:56Z",
"created_by_email": "<string>",
"created_by_name": "<string>",
"created_by_user_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"last_change_note": "<string>",
"last_modified_at": "2023-11-07T05:31:56Z",
"last_modified_by_email": "<string>",
"last_modified_by_name": "<string>",
"last_modified_by_user_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"billing_note": "<string>",
"billing_reason": "subscription",
"catalog_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"catalog_slug": "<string>",
"connection_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"health_checked_at": "2023-11-07T05:31:56Z",
"health_detail": "<string>",
"request_timeout_secs": 123,
"stream_idle_timeout_secs": 123
}
]Authorizations
A Barndoor API key, sent as Authorization: Bearer <key>. Keys are prefixed bdai_ and are opaque — do not attempt to decode one. Interchangeable with an OAuth 2.0 access token.
Response
The requested record
Whether the gateway records a per-token cost for this provider's
traffic (V69 / BCP-3876). PerToken for every provider that has not
opted in, which is the default and the back-compat value.
The request path does not read this field: billing consults
[ai_governance::CostCalculator]'s own cached not-metered set, which
is refreshed from the same query as pricing. This exists for the admin
API surface and the audit trail.
per_token, not_metered Operator override for the health gate (V46). When true (default)
routing requires health_status <> 'unhealthy'; when false the gate
is bypassed and the provider serves regardless of probe results (we
still probe and surface health). Lets an admin force traffic through a
false-positive probe.
Observed upstream reachability, recorded separately from enabled
(operator intent) so the system never overwrites the toggle (V45).
One of unverified | healthy | unhealthy. unverified is the
back-compat default and also covers provider families we don't probe
(Bedrock/Vertex/Azure, claude_oauth, codex_oauth). A provider serves traffic only
when enabled AND health_status <> 'unhealthy': a failed probe
auto-suspends it from routing (see resolve_*) without disabling it,
and it resumes once a probe records it healthy again.
Whether this provider tracks Barndoor's model catalog, and how far
(V63 / BCP-3811). Off for every provider that has not opted in,
which is the default and the back-compat value.
off, additive, full Optional free text explaining why the last change was made ("Raised for the Q3 batch job", "Vendor deprecated the old endpoint").
Admin-authored and rendered in the portal, so it is untrusted input: length-capped here, escaped on render.
When the change named by last_modified_by_* happened.
Its own column rather than the row's updated_at, because updated_at
is bumped by writes nobody is attributed for -- pairing the two would
date a named admin's edit to a background job's clock. See the V75
migration for the full reasoning.
Optional free-text context for the arrangement (max 200 chars). Human-readable only — never parsed, never aggregated.
How the vendor bills this provider. Required when billing_mode is
NotMetered, optional otherwise (V69 CHECK-enforced) — a subscription
billing overages is both per-token and a subscription. Purely
descriptive: no code branches on it, which is what lets a new reason be
added without touching the billing path.
subscription, local, external, other When the last connectivity probe ran (NULL until the first probe).
Reason for the last unhealthy or unverified probe (NULL if healthy or never probed).
Provider-tier total-request timeout override (non-streaming).
Operator-only and None by default: the effective value is written
at the route tier (model_mappings), so this only applies if a route
row somehow leaves it unset. Range
TOTAL_REQUEST_TIMEOUT_MIN_SECS..=TOTAL_REQUEST_TIMEOUT_MAX_SECS is
enforced by the CHECK constraint (see proxy::timeouts).
Provider-tier stream-idle timeout override (streaming). Operator-only
and None by default; the effective value is written at the route
tier (model_mappings). Range
STREAM_IDLE_TIMEOUT_MIN_SECS..=STREAM_IDLE_TIMEOUT_MAX_SECS is
enforced by the CHECK constraint (see proxy::timeouts).