curl --request POST \
--url https://{host}/api/llm-gateway/admin/api-keys \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "<string>",
"expires_at": "2023-11-07T05:31:56Z",
"group_name": "<string>",
"scopes": [
"<string>"
],
"user_email": "<string>",
"user_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
'import requests
url = "https://{host}/api/llm-gateway/admin/api-keys"
payload = {
"name": "<string>",
"expires_at": "2023-11-07T05:31:56Z",
"group_name": "<string>",
"scopes": ["<string>"],
"user_email": "<string>",
"user_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
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({
name: '<string>',
expires_at: '2023-11-07T05:31:56Z',
group_name: '<string>',
scopes: ['<string>'],
user_email: '<string>',
user_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a'
})
};
fetch('https://{host}/api/llm-gateway/admin/api-keys', 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/api-keys",
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([
'name' => '<string>',
'expires_at' => '2023-11-07T05:31:56Z',
'group_name' => '<string>',
'scopes' => [
'<string>'
],
'user_email' => '<string>',
'user_id' => '3c90c3cc-0d44-4b50-8888-8dd25736052a'
]),
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/api-keys"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"expires_at\": \"2023-11-07T05:31:56Z\",\n \"group_name\": \"<string>\",\n \"scopes\": [\n \"<string>\"\n ],\n \"user_email\": \"<string>\",\n \"user_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\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/api-keys")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"expires_at\": \"2023-11-07T05:31:56Z\",\n \"group_name\": \"<string>\",\n \"scopes\": [\n \"<string>\"\n ],\n \"user_email\": \"<string>\",\n \"user_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://{host}/api/llm-gateway/admin/api-keys")
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 \"name\": \"<string>\",\n \"expires_at\": \"2023-11-07T05:31:56Z\",\n \"group_name\": \"<string>\",\n \"scopes\": [\n \"<string>\"\n ],\n \"user_email\": \"<string>\",\n \"user_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n}"
response = http.request(request)
puts response.read_body{
"created_at": "2023-11-07T05:31:56Z",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"key": "<string>",
"key_prefix": "<string>",
"name": "<string>",
"scopes": [
"<string>"
],
"expires_at": "2023-11-07T05:31:56Z",
"group_name": "<string>"
}{
"error": {
"message": "retry_on_429_count must be between 0 and 10",
"type": "invalid_request_error"
}
}{
"error": {
"message": "retry_on_429_count must be between 0 and 10",
"type": "invalid_request_error"
}
}{
"error": {
"message": "retry_on_429_count must be between 0 and 10",
"type": "invalid_request_error"
}
}{
"error": {
"message": "retry_on_429_count must be between 0 and 10",
"type": "invalid_request_error"
}
}{
"error": {
"message": "retry_on_429_count must be between 0 and 10",
"type": "invalid_request_error"
}
}Create an Org API Key
Creates a bd-... gateway API key for LLM traffic. The raw key is returned in this response and never again, so copy it immediately.
Assign the key to a person with user_id, bind it to an IdP group with group_name, or omit both for a service key. user_id and group_name cannot be combined.
curl --request POST \
--url https://{host}/api/llm-gateway/admin/api-keys \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "<string>",
"expires_at": "2023-11-07T05:31:56Z",
"group_name": "<string>",
"scopes": [
"<string>"
],
"user_email": "<string>",
"user_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
'import requests
url = "https://{host}/api/llm-gateway/admin/api-keys"
payload = {
"name": "<string>",
"expires_at": "2023-11-07T05:31:56Z",
"group_name": "<string>",
"scopes": ["<string>"],
"user_email": "<string>",
"user_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
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({
name: '<string>',
expires_at: '2023-11-07T05:31:56Z',
group_name: '<string>',
scopes: ['<string>'],
user_email: '<string>',
user_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a'
})
};
fetch('https://{host}/api/llm-gateway/admin/api-keys', 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/api-keys",
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([
'name' => '<string>',
'expires_at' => '2023-11-07T05:31:56Z',
'group_name' => '<string>',
'scopes' => [
'<string>'
],
'user_email' => '<string>',
'user_id' => '3c90c3cc-0d44-4b50-8888-8dd25736052a'
]),
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/api-keys"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"expires_at\": \"2023-11-07T05:31:56Z\",\n \"group_name\": \"<string>\",\n \"scopes\": [\n \"<string>\"\n ],\n \"user_email\": \"<string>\",\n \"user_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\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/api-keys")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"expires_at\": \"2023-11-07T05:31:56Z\",\n \"group_name\": \"<string>\",\n \"scopes\": [\n \"<string>\"\n ],\n \"user_email\": \"<string>\",\n \"user_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://{host}/api/llm-gateway/admin/api-keys")
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 \"name\": \"<string>\",\n \"expires_at\": \"2023-11-07T05:31:56Z\",\n \"group_name\": \"<string>\",\n \"scopes\": [\n \"<string>\"\n ],\n \"user_email\": \"<string>\",\n \"user_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n}"
response = http.request(request)
puts response.read_body{
"created_at": "2023-11-07T05:31:56Z",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"key": "<string>",
"key_prefix": "<string>",
"name": "<string>",
"scopes": [
"<string>"
],
"expires_at": "2023-11-07T05:31:56Z",
"group_name": "<string>"
}{
"error": {
"message": "retry_on_429_count must be between 0 and 10",
"type": "invalid_request_error"
}
}{
"error": {
"message": "retry_on_429_count must be between 0 and 10",
"type": "invalid_request_error"
}
}{
"error": {
"message": "retry_on_429_count must be between 0 and 10",
"type": "invalid_request_error"
}
}{
"error": {
"message": "retry_on_429_count must be between 0 and 10",
"type": "invalid_request_error"
}
}{
"error": {
"message": "retry_on_429_count must be between 0 and 10",
"type": "invalid_request_error"
}
}bd-… API key for the LLM Gateway runtime
(/v1/chat/completions, /v1/messages, /v1/embeddings, etc.).
user_id), bound to an IdP group
(group_name), or neither (a service key), but never both. Use the binding to control scope of:
- per-user/per-group budgets
- per-user/per-group rate limits
- per-user/per-group model access policies
Example: a CI service-account key
curl -X POST https://app.barndoor.ai/api/llm-gateway/admin/api-keys \
-H "Authorization: Bearer $BARNDOOR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "GitHub Actions runner",
"group_name": "ci",
"expires_at": "2026-12-31T23:59:59Z"
}'
key. From that point on, callers can use it as:
curl https://app.barndoor.ai/api/llm-gateway/v1/chat/completions \
-H "Authorization: Bearer bd-..." \
-H "Content-Type: application/json" \
-d '{ "model": "gpt-5.4-mini", "messages": [...] }'
DELETE /admin/api-keys/{id}.
To stop a key temporarily without reissuing it, disable it
instead.Authorizations
An access token from Barndoor's identity provider, sent as Authorization: Bearer <token>. Use a service-account token from the OAuth 2.0 client-credentials grant for scripts and CI, or a signed-in user's token. The caller needs the admin role in the organization. Gateway API keys (bd-...) are not accepted here.
Body
When the key stops working. Omit for a key that does not expire.
IdP group to bind the key to, such as engineering. Requests with the key are governed by that group's budgets, rate limits, and model access policies. Cannot be combined with user_id.
Email to record on the key. Defaults to the caller's email.
User to assign the key to. Cannot be combined with group_name. Omit both for a service key.