API Keys
Create Organization API Key
Programmatically create an API key owned by an organization.
POST /api/organizations/:organizationId/api-keysCreates an API key owned by the organization itself, rather than by your user account. The key authenticates as the organization (org-admin authority over its sites), so it survives member departures, and its plan gating, rate limits, and key-count limit all follow the owning organization's subscription. Organization keys are issued with the rb_org_ prefix.
You must be an owner or admin of the target organization. This endpoint accepts your dashboard session or an unrestricted (full-access) user API key — scoped keys and organization keys are rejected, so an organization key cannot mint other keys.
Path Parameters
Prop
Type
Request Body
Prop
Type
Response
Returns the created API key object. The full key value carries the rb_org_ prefix.
Prop
Type
Note: Additional fields may be present in the response object.
curl -X POST "https://app.rybbit.io/api/organizations/org_123/api-keys" \
-H "Cookie: better-auth.session_token=YOUR_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "CI pipeline", "expiresIn": 2592000}'const response = await fetch(
'https://app.rybbit.io/api/organizations/org_123/api-keys',
{
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'CI pipeline',
expiresIn: 2592000
})
}
);
const data = await response.json();import requests
response = requests.post(
'https://app.rybbit.io/api/organizations/org_123/api-keys',
json={
'name': 'CI pipeline',
'expiresIn': 2592000
},
headers={
'Cookie': 'better-auth.session_token=YOUR_SESSION_TOKEN'
}
)
data = response.json()$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://app.rybbit.io/api/organizations/org_123/api-keys");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
'name' => 'CI pipeline',
'expiresIn' => 2592000
]));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Cookie: better-auth.session_token=YOUR_SESSION_TOKEN',
'Content-Type: application/json'
]);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);require 'net/http'
require 'json'
uri = URI("https://app.rybbit.io/api/organizations/org_123/api-keys")
req = Net::HTTP::Post.new(uri)
req['Cookie'] = 'better-auth.session_token=YOUR_SESSION_TOKEN'
req['Content-Type'] = 'application/json'
req.body = {
name: 'CI pipeline',
expiresIn: 2592000
}.to_json
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
data = JSON.parse(res.body)body := bytes.NewBuffer([]byte(`{
"name": "CI pipeline",
"expiresIn": 2592000
}`))
req, _ := http.NewRequest("POST", "https://app.rybbit.io/api/organizations/org_123/api-keys", body)
req.Header.Set("Cookie", "better-auth.session_token=YOUR_SESSION_TOKEN")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
var data map[string]interface{}
json.NewDecoder(resp.Body).Decode(&data)let client = reqwest::Client::new();
let res = client
.post("https://app.rybbit.io/api/organizations/org_123/api-keys")
.header("Cookie", "better-auth.session_token=YOUR_SESSION_TOKEN")
.json(&serde_json::json!({
"name": "CI pipeline",
"expiresIn": 2592000
}))
.send()
.await?;
let data: serde_json::Value = res.json().await?;HttpClient client = HttpClient.newHttpClient();
String json = "{\"name\": \"CI pipeline\", \"expiresIn\": 2592000}";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://app.rybbit.io/api/organizations/org_123/api-keys"))
.header("Cookie", "better-auth.session_token=YOUR_SESSION_TOKEN")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(json))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());using var client = new HttpClient();
client.DefaultRequestHeaders.Add("Cookie", "better-auth.session_token=YOUR_SESSION_TOKEN");
var content = new StringContent(
"{\"name\": \"CI pipeline\", \"expiresIn\": 2592000}",
Encoding.UTF8,
"application/json"
);
var response = await client.PostAsync("https://app.rybbit.io/api/organizations/org_123/api-keys", content);
var data = await response.Content.ReadAsStringAsync();The full
key value is returned only once, at creation. Store it securely — it cannot be retrieved again.{
"id": "key_8f3a1b2c4d5e6f7g",
"key": "rb_org_xxxxxxxxxxxxxxxxxxxx",
"name": "CI pipeline",
"start": "rb_org_xxxx",
"prefix": "rb_org_",
"referenceId": "org_123",
"userId": "user_2a9b8c7d6e5f4g3h",
"enabled": true,
"expiresAt": "2026-07-25T12:00:00.000Z",
"createdAt": "2026-06-25T12:00:00.000Z",
"updatedAt": "2026-06-25T12:00:00.000Z",
"rateLimitEnabled": true,
"rateLimitMax": 200,
"rateLimitTimeWindow": 60000
}On Rybbit Cloud, organization API keys require the organization to be on a Standard or Pro plan; free/basic plans receive HTTP 403. Each organization also has a plan-based key-count limit — creating a key past the limit returns HTTP 403.