curl --request POST \
--url https://{host}/api/llm-gateway/admin/connections \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"base_url": "<string>",
"model_provider": "<string>",
"name": "<string>",
"api_key": "<string>",
"auth_type": "<string>",
"change_note": "<string>",
"credentials": "<unknown>",
"settings": "<unknown>"
}
'import requests
url = "https://{host}/api/llm-gateway/admin/connections"
payload = {
"base_url": "<string>",
"model_provider": "<string>",
"name": "<string>",
"api_key": "<string>",
"auth_type": "<string>",
"change_note": "<string>",
"credentials": "<unknown>",
"settings": "<unknown>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
base_url: '<string>',
model_provider: '<string>',
name: '<string>',
api_key: '<string>',
auth_type: '<string>',
change_note: '<string>',
credentials: '<unknown>',
settings: '<unknown>'
})
};
fetch('https://{host}/api/llm-gateway/admin/connections', 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/connections",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'base_url' => '<string>',
'model_provider' => '<string>',
'name' => '<string>',
'api_key' => '<string>',
'auth_type' => '<string>',
'change_note' => '<string>',
'credentials' => '<unknown>',
'settings' => '<unknown>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://{host}/api/llm-gateway/admin/connections"
payload := strings.NewReader("{\n \"base_url\": \"<string>\",\n \"model_provider\": \"<string>\",\n \"name\": \"<string>\",\n \"api_key\": \"<string>\",\n \"auth_type\": \"<string>\",\n \"change_note\": \"<string>\",\n \"credentials\": \"<unknown>\",\n \"settings\": \"<unknown>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://{host}/api/llm-gateway/admin/connections")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"base_url\": \"<string>\",\n \"model_provider\": \"<string>\",\n \"name\": \"<string>\",\n \"api_key\": \"<string>\",\n \"auth_type\": \"<string>\",\n \"change_note\": \"<string>\",\n \"credentials\": \"<unknown>\",\n \"settings\": \"<unknown>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://{host}/api/llm-gateway/admin/connections")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"base_url\": \"<string>\",\n \"model_provider\": \"<string>\",\n \"name\": \"<string>\",\n \"api_key\": \"<string>\",\n \"auth_type\": \"<string>\",\n \"change_note\": \"<string>\",\n \"credentials\": \"<unknown>\",\n \"settings\": \"<unknown>\"\n}"
response = http.request(request)
puts response.read_body{
"auth_type": "<string>",
"base_url": "<string>",
"created_at": "2023-11-07T05:31:56Z",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"model_provider": "<string>",
"name": "<string>",
"org_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"secret_path": "<string>",
"settings": "<unknown>",
"stores_key_material": true,
"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",
"key_last4": "<string>"
}Create a provider connection
curl --request POST \
--url https://{host}/api/llm-gateway/admin/connections \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"base_url": "<string>",
"model_provider": "<string>",
"name": "<string>",
"api_key": "<string>",
"auth_type": "<string>",
"change_note": "<string>",
"credentials": "<unknown>",
"settings": "<unknown>"
}
'import requests
url = "https://{host}/api/llm-gateway/admin/connections"
payload = {
"base_url": "<string>",
"model_provider": "<string>",
"name": "<string>",
"api_key": "<string>",
"auth_type": "<string>",
"change_note": "<string>",
"credentials": "<unknown>",
"settings": "<unknown>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
base_url: '<string>',
model_provider: '<string>',
name: '<string>',
api_key: '<string>',
auth_type: '<string>',
change_note: '<string>',
credentials: '<unknown>',
settings: '<unknown>'
})
};
fetch('https://{host}/api/llm-gateway/admin/connections', 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/connections",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'base_url' => '<string>',
'model_provider' => '<string>',
'name' => '<string>',
'api_key' => '<string>',
'auth_type' => '<string>',
'change_note' => '<string>',
'credentials' => '<unknown>',
'settings' => '<unknown>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://{host}/api/llm-gateway/admin/connections"
payload := strings.NewReader("{\n \"base_url\": \"<string>\",\n \"model_provider\": \"<string>\",\n \"name\": \"<string>\",\n \"api_key\": \"<string>\",\n \"auth_type\": \"<string>\",\n \"change_note\": \"<string>\",\n \"credentials\": \"<unknown>\",\n \"settings\": \"<unknown>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://{host}/api/llm-gateway/admin/connections")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"base_url\": \"<string>\",\n \"model_provider\": \"<string>\",\n \"name\": \"<string>\",\n \"api_key\": \"<string>\",\n \"auth_type\": \"<string>\",\n \"change_note\": \"<string>\",\n \"credentials\": \"<unknown>\",\n \"settings\": \"<unknown>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://{host}/api/llm-gateway/admin/connections")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"base_url\": \"<string>\",\n \"model_provider\": \"<string>\",\n \"name\": \"<string>\",\n \"api_key\": \"<string>\",\n \"auth_type\": \"<string>\",\n \"change_note\": \"<string>\",\n \"credentials\": \"<unknown>\",\n \"settings\": \"<unknown>\"\n}"
response = http.request(request)
puts response.read_body{
"auth_type": "<string>",
"base_url": "<string>",
"created_at": "2023-11-07T05:31:56Z",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"model_provider": "<string>",
"name": "<string>",
"org_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"secret_path": "<string>",
"settings": "<unknown>",
"stores_key_material": true,
"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",
"key_last4": "<string>"
}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.
Body
Optional free-text note explaining why this credential was added (BCP-3998). Never a place for key material — the portal's placeholder copy asks for intent, and the value is stored in plaintext on the row and mirrored into the audit event.
Response
The created record
Every column of llm_gw.connections, plus one derived field.
Serialized straight to the admin API — there is no separate response type,
which is safe because no column here holds key material. secret_path is a
pointer into OpenBao; key_last4 is four characters of a tail (BCP-3821).
Whether this credential's auth type holds a secret at all. Derived from
auth_type, not stored: it is a property of the auth type, so a column
would be a second copy of the same fact, free to drift.
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.
Last four characters of the stored key, once known.
None means "no tail to show", which is three different situations —
stores_key_material is what tells them apart. Populated whenever key
material is written, and derived on first read for credentials that
predate the column.