Chei API
7 endpoint-uri. Fiecare cale de mai jos este relativă la URL-ul de bază al API-ului și include deja prefixul /api/v1 — vezi convențiile pentru autentificare, paginare, erori și idempotență.
| Endpoint | ||
|---|---|---|
| GET | /api-keys | List API keys newest first, filterable by type and active state; private key material is never included |
| POST | /api-keys | Issue an API key and return its plaintext once — this is the only response that ever contains it |
| GET | /api-keys/{apiKey} | Retrieve one API key by id; a private key's material is reduced to its prefix and last four |
| PUT | /api-keys/{apiKey} | Update a key's name, scopes, restrictions or expiry. Key material is immutable |
| DELETE | /api-keys/{apiKey} | Revoke a key immediately and return the revoked key object |
| POST | /api-keys/{apiKey}/rotate | Mint a replacement key, return its plaintext, and expire the old key after an overlap window |
| GET | /api-keys/scopes | List the scope vocabulary an API key may be granted, grouped by permission area |
Endpoint-uri
List API keys newest first, filterable by type and active state; private key material is never included
- Necesită
api_key.read. - Query filters are type and active_only; per_page is clamped to 100.
Parametri de interogare
| Nume | Tip | Obligatoriu | Note |
|---|---|---|---|
active_only | boolean | — | default false |
curl -X GET "$CALLAGENT_API_URL/api-keys?active_only=false" \
-H "Authorization: Bearer $CALLAGENT_API_KEY" \
-H "Accept: application/json"const response = await fetch(`${process.env.CALLAGENT_API_URL}/api-keys?active_only=false`, {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.CALLAGENT_API_KEY}`,
Accept: 'application/json',
},
});
if (!response.ok) {
const { error } = await response.json();
throw new Error(`${error.type}: ${error.message}`);
}
const { data } = await response.json();<?php
$handle = curl_init(getenv('CALLAGENT_API_URL') . '/api-keys?active_only=false');
curl_setopt_array($handle, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('CALLAGENT_API_KEY'),
'Accept: application/json',
],
]);
$body = json_decode(curl_exec($handle), true);
$status = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);
if ($status >= 400) {
throw new RuntimeException("{$body['error']['type']}: {$body['error']['message']}");
}
$data = $body['data'];import os, requests
response = requests.get(
f"{os.environ['CALLAGENT_API_URL']}/api-keys?active_only=false",
headers={"Authorization": f"Bearer {os.environ['CALLAGENT_API_KEY']}"},
timeout=30,
)
response.raise_for_status()
data = response.json()["data"]Răspunsuri
| Status | Corp |
|---|---|
200 | Array of ApiKeyResource |
Erori
| Status | Când apare |
|---|---|
403 | The presenting API key does not carry the api_key.read scope |
Exemplu de răspuns, generat din schemă:
{
"data": [
{
"id": "01JQ0000000000000000000000",
"object": "string",
"name": "Support Line",
"type": "string",
"display": "string",
"public_key": "string",
"scopes": {},
"allowed_origins": {},
"allowed_assistant_ids": {},
"allowed_ips": {},
"expires_at": "2026-01-01T12:00:00+00:00",
"last_used_at": "2026-01-01T12:00:00+00:00",
"last_used_ip": "string",
"revoked_at": "2026-01-01T12:00:00+00:00",
"rotated_from_id": "01JQ0000000000000000000000",
"usable": true,
"created_at": "2026-01-01T12:00:00+00:00"
}
]
}Issue an API key and return its plaintext once — this is the only response that ever contains it
A public key must carry at least one allowed origin — it ships inside a browser bundle, so origin restriction is the only thing protecting it.
- Necesită
api_key.write. - type=public is refused unless allowed_origins is non-empty. Scopes accept '' and 'group.' wildcards; anything else must exist in the vocabulary.
Corpul cererii
| Câmp | Tip | Obligatoriu | Note |
|---|---|---|---|
name | string | da | max 255 chars |
type | private · public · service_account · null | null | — | |
scopes | string[] | null | — | |
allowed_origins | string[] | null | — | |
allowed_assistant_ids | string[] | null | — | |
allowed_ips | string[] | null | — | |
expires_at | string | null | — | date-time |
curl -X POST "$CALLAGENT_API_URL/api-keys" \
-H "Authorization: Bearer $CALLAGENT_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"name": "Support Line",
"type": "private",
"expires_at": "2026-01-01T12:00:00+00:00"
}'const response = await fetch(`${process.env.CALLAGENT_API_URL}/api-keys`, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.CALLAGENT_API_KEY}`,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"name": "Support Line",
"type": "private",
"expires_at": "2026-01-01T12:00:00+00:00"
}),
});
if (!response.ok) {
const { error } = await response.json();
throw new Error(`${error.type}: ${error.message}`);
}
const { data } = await response.json();<?php
$handle = curl_init(getenv('CALLAGENT_API_URL') . '/api-keys');
curl_setopt_array($handle, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('CALLAGENT_API_KEY'),
'Accept: application/json',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'name' => 'Support Line',
'type' => 'private',
'expires_at' => '2026-01-01T12:00:00+00:00',
]),
]);
$body = json_decode(curl_exec($handle), true);
$status = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);
if ($status >= 400) {
throw new RuntimeException("{$body['error']['type']}: {$body['error']['message']}");
}
$data = $body['data'];import os, requests
response = requests.post(
f"{os.environ['CALLAGENT_API_URL']}/api-keys",
headers={"Authorization": f"Bearer {os.environ['CALLAGENT_API_KEY']}"},
json={
"name": "Support Line",
"type": "private",
"expires_at": "2026-01-01T12:00:00+00:00"
},
timeout=30,
)
response.raise_for_status()
data = response.json()["data"]Răspunsuri
| Status | Corp |
|---|---|
201 | data-wrapped object |
Erori
| Status | Când apare |
|---|---|
403 | The presenting API key does not carry the api_key.write scope |
422 | Validation failed, an unknown scope was requested, or a public key had no allowed_origins |
Exemplu de răspuns, generat din schemă:
{
"data": {
"id": "01JQ0000000000000000000000",
"name": "Support Line",
"type": "string",
"key": "string",
"key_prefix": "string",
"last_four": "string",
"scopes": {},
"expires_at": "2026-01-01T12:00:00+00:00",
"notice": "This is a public key. It is safe to ship in a browser bundle, but restrict it by origin and assistant."
}
}Retrieve one API key by id; a private key's material is reduced to its prefix and last four
- Necesită
api_key.read.
Parametri de cale
| Nume | Tip | Obligatoriu | Note |
|---|---|---|---|
apiKey | string | da | The api key ID |
curl -X GET "$CALLAGENT_API_URL/api-keys/01JQ0000000000000000000000" \
-H "Authorization: Bearer $CALLAGENT_API_KEY" \
-H "Accept: application/json"const response = await fetch(`${process.env.CALLAGENT_API_URL}/api-keys/01JQ0000000000000000000000`, {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.CALLAGENT_API_KEY}`,
Accept: 'application/json',
},
});
if (!response.ok) {
const { error } = await response.json();
throw new Error(`${error.type}: ${error.message}`);
}
const { data } = await response.json();<?php
$handle = curl_init(getenv('CALLAGENT_API_URL') . '/api-keys/01JQ0000000000000000000000');
curl_setopt_array($handle, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('CALLAGENT_API_KEY'),
'Accept: application/json',
],
]);
$body = json_decode(curl_exec($handle), true);
$status = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);
if ($status >= 400) {
throw new RuntimeException("{$body['error']['type']}: {$body['error']['message']}");
}
$data = $body['data'];import os, requests
response = requests.get(
f"{os.environ['CALLAGENT_API_URL']}/api-keys/01JQ0000000000000000000000",
headers={"Authorization": f"Bearer {os.environ['CALLAGENT_API_KEY']}"},
timeout=30,
)
response.raise_for_status()
data = response.json()["data"]Răspunsuri
| Status | Corp |
|---|---|
200 | ApiKeyResource |
Erori
| Status | Când apare |
|---|---|
403 | The presenting API key does not carry the api_key.read scope |
404 | No such key in this organization |
Exemplu de răspuns, generat din schemă:
{
"data": {
"id": "01JQ0000000000000000000000",
"object": "string",
"name": "Support Line",
"type": "string",
"display": "string",
"public_key": "string",
"scopes": {},
"allowed_origins": {},
"allowed_assistant_ids": {},
"allowed_ips": {},
"expires_at": "2026-01-01T12:00:00+00:00",
"last_used_at": "2026-01-01T12:00:00+00:00",
"last_used_ip": "string",
"revoked_at": "2026-01-01T12:00:00+00:00",
"rotated_from_id": "01JQ0000000000000000000000",
"usable": true,
"created_at": "2026-01-01T12:00:00+00:00"
}
}Update a key's name, scopes, restrictions or expiry. Key material is immutable
- Necesită
api_key.write. PATCHeste acceptat pe aceeași cale, cu același corp.- type, key_hash, public_key, key_prefix, last_four and organization_id are silently dropped rather than rejected.
Parametri de cale
| Nume | Tip | Obligatoriu | Note |
|---|---|---|---|
apiKey | string | da | The api key ID |
Corpul cererii
| Câmp | Tip | Obligatoriu | Note |
|---|---|---|---|
name | string | — | max 255 chars |
scopes | string[] | — | |
allowed_origins | string[] | — | |
allowed_assistant_ids | string[] | — | |
allowed_ips | string[] | — | |
expires_at | string | null | — | date-time |
curl -X PUT "$CALLAGENT_API_URL/api-keys/01JQ0000000000000000000000" \
-H "Authorization: Bearer $CALLAGENT_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"name": "Support Line",
"expires_at": "2026-01-01T12:00:00+00:00"
}'const response = await fetch(`${process.env.CALLAGENT_API_URL}/api-keys/01JQ0000000000000000000000`, {
method: 'PUT',
headers: {
Authorization: `Bearer ${process.env.CALLAGENT_API_KEY}`,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"name": "Support Line",
"expires_at": "2026-01-01T12:00:00+00:00"
}),
});
if (!response.ok) {
const { error } = await response.json();
throw new Error(`${error.type}: ${error.message}`);
}
const { data } = await response.json();<?php
$handle = curl_init(getenv('CALLAGENT_API_URL') . '/api-keys/01JQ0000000000000000000000');
curl_setopt_array($handle, [
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('CALLAGENT_API_KEY'),
'Accept: application/json',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'name' => 'Support Line',
'expires_at' => '2026-01-01T12:00:00+00:00',
]),
]);
$body = json_decode(curl_exec($handle), true);
$status = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);
if ($status >= 400) {
throw new RuntimeException("{$body['error']['type']}: {$body['error']['message']}");
}
$data = $body['data'];import os, requests
response = requests.put(
f"{os.environ['CALLAGENT_API_URL']}/api-keys/01JQ0000000000000000000000",
headers={"Authorization": f"Bearer {os.environ['CALLAGENT_API_KEY']}"},
json={
"name": "Support Line",
"expires_at": "2026-01-01T12:00:00+00:00"
},
timeout=30,
)
response.raise_for_status()
data = response.json()["data"]Răspunsuri
| Status | Corp |
|---|---|
200 | ApiKeyResource |
Erori
| Status | Când apare |
|---|---|
403 | The presenting API key does not carry the api_key.write scope |
404 | No such key in this organization |
422 | Validation failed or an unknown scope was requested |
Exemplu de răspuns, generat din schemă:
{
"data": {
"id": "01JQ0000000000000000000000",
"object": "string",
"name": "Support Line",
"type": "string",
"display": "string",
"public_key": "string",
"scopes": {},
"allowed_origins": {},
"allowed_assistant_ids": {},
"allowed_ips": {},
"expires_at": "2026-01-01T12:00:00+00:00",
"last_used_at": "2026-01-01T12:00:00+00:00",
"last_used_ip": "string",
"revoked_at": "2026-01-01T12:00:00+00:00",
"rotated_from_id": "01JQ0000000000000000000000",
"usable": true,
"created_at": "2026-01-01T12:00:00+00:00"
}
}Revoke a key immediately and return the revoked key object
- Necesită
api_key.write. - DELETE does not delete: it stamps revoked_at and returns 200 with a body, not 204. An optional
reasonis recorded in the audit log.
Parametri de cale
| Nume | Tip | Obligatoriu | Note |
|---|---|---|---|
apiKey | string | da | The api key ID |
curl -X DELETE "$CALLAGENT_API_URL/api-keys/01JQ0000000000000000000000" \
-H "Authorization: Bearer $CALLAGENT_API_KEY" \
-H "Accept: application/json"const response = await fetch(`${process.env.CALLAGENT_API_URL}/api-keys/01JQ0000000000000000000000`, {
method: 'DELETE',
headers: {
Authorization: `Bearer ${process.env.CALLAGENT_API_KEY}`,
Accept: 'application/json',
},
});
if (!response.ok) {
const { error } = await response.json();
throw new Error(`${error.type}: ${error.message}`);
}
const { data } = await response.json();<?php
$handle = curl_init(getenv('CALLAGENT_API_URL') . '/api-keys/01JQ0000000000000000000000');
curl_setopt_array($handle, [
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('CALLAGENT_API_KEY'),
'Accept: application/json',
],
]);
$body = json_decode(curl_exec($handle), true);
$status = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);
if ($status >= 400) {
throw new RuntimeException("{$body['error']['type']}: {$body['error']['message']}");
}
$data = $body['data'];import os, requests
response = requests.delete(
f"{os.environ['CALLAGENT_API_URL']}/api-keys/01JQ0000000000000000000000",
headers={"Authorization": f"Bearer {os.environ['CALLAGENT_API_KEY']}"},
timeout=30,
)
response.raise_for_status()
data = response.json()["data"]Răspunsuri
| Status | Corp |
|---|---|
200 | data-wrapped object |
Erori
| Status | Când apare |
|---|---|
403 | The presenting API key does not carry the api_key.write scope |
404 | No such key in this organization |
Exemplu de răspuns, generat din schemă:
{
"data": {
"id": "01JQ0000000000000000000000",
"object": "string",
"name": "Support Line",
"type": "string",
"display": "string",
"public_key": "string",
"scopes": {},
"allowed_origins": {},
"allowed_assistant_ids": {},
"allowed_ips": {},
"expires_at": "2026-01-01T12:00:00+00:00",
"last_used_at": "2026-01-01T12:00:00+00:00",
"last_used_ip": "string",
"revoked_at": "2026-01-01T12:00:00+00:00",
"rotated_from_id": "01JQ0000000000000000000000",
"usable": true,
"created_at": "2026-01-01T12:00:00+00:00"
}
}Mint a replacement key, return its plaintext, and expire the old key after an overlap window
Returns the replacement's plaintext. The old key keeps working for overlap_hours so a rolling deploy does not break; pass 0 after a leak.
- Necesită
api_key.write. - The response has a sibling
rotated_fromnext todata. overlap_hours defaults to 24; 0 revokes the old key immediately.
Parametri de cale
| Nume | Tip | Obligatoriu | Note |
|---|---|---|---|
apiKey | string | da | The api key ID |
Corpul cererii
| Câmp | Tip | Obligatoriu | Note |
|---|---|---|---|
overlap_hours | integer | null | — | min 0. max 720 |
curl -X POST "$CALLAGENT_API_URL/api-keys/01JQ0000000000000000000000/rotate" \
-H "Authorization: Bearer $CALLAGENT_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"overlap_hours": 1
}'const response = await fetch(`${process.env.CALLAGENT_API_URL}/api-keys/01JQ0000000000000000000000/rotate`, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.CALLAGENT_API_KEY}`,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"overlap_hours": 1
}),
});
if (!response.ok) {
const { error } = await response.json();
throw new Error(`${error.type}: ${error.message}`);
}
const { data } = await response.json();<?php
$handle = curl_init(getenv('CALLAGENT_API_URL') . '/api-keys/01JQ0000000000000000000000/rotate');
curl_setopt_array($handle, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('CALLAGENT_API_KEY'),
'Accept: application/json',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'overlap_hours' => 1,
]),
]);
$body = json_decode(curl_exec($handle), true);
$status = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);
if ($status >= 400) {
throw new RuntimeException("{$body['error']['type']}: {$body['error']['message']}");
}
$data = $body['data'];import os, requests
response = requests.post(
f"{os.environ['CALLAGENT_API_URL']}/api-keys/01JQ0000000000000000000000/rotate",
headers={"Authorization": f"Bearer {os.environ['CALLAGENT_API_KEY']}"},
json={
"overlap_hours": 1
},
timeout=30,
)
response.raise_for_status()
data = response.json()["data"]Răspunsuri
| Status | Corp |
|---|---|
201 | data-wrapped object |
Erori
| Status | Când apare |
|---|---|
403 | The presenting API key does not carry the api_key.write scope |
404 | No such key in this organization |
422 | overlap_hours is not an integer in 0..720 |
Exemplu de răspuns, generat din schemă:
{
"data": {
"id": "01JQ0000000000000000000000",
"name": "Support Line",
"type": "string",
"key": "string",
"key_prefix": "string",
"last_four": "string",
"scopes": {},
"expires_at": "2026-01-01T12:00:00+00:00",
"notice": "This is a public key. It is safe to ship in a browser bundle, but restrict it by origin and assistant."
},
"rotated_from": {
"id": "01JQ0000000000000000000000",
"object": "string",
"name": "Support Line",
"type": "string",
"display": "string",
"public_key": "string",
"scopes": {},
"allowed_origins": {},
"allowed_assistant_ids": {},
"allowed_ips": {},
"expires_at": "2026-01-01T12:00:00+00:00",
"last_used_at": "2026-01-01T12:00:00+00:00",
"last_used_ip": "string",
"revoked_at": "2026-01-01T12:00:00+00:00",
"rotated_from_id": "01JQ0000000000000000000000",
"usable": true,
"created_at": "2026-01-01T12:00:00+00:00"
}
}List the scope vocabulary an API key may be granted, grouped by permission area
- Handler-ul nu impune niciun scope — orice cheie validă îl poate apela.
- The only api-keys endpoint that enforces no scope at all — any authenticated key can read it.
curl -X GET "$CALLAGENT_API_URL/api-keys/scopes" \
-H "Authorization: Bearer $CALLAGENT_API_KEY" \
-H "Accept: application/json"const response = await fetch(`${process.env.CALLAGENT_API_URL}/api-keys/scopes`, {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.CALLAGENT_API_KEY}`,
Accept: 'application/json',
},
});
if (!response.ok) {
const { error } = await response.json();
throw new Error(`${error.type}: ${error.message}`);
}
const { data } = await response.json();<?php
$handle = curl_init(getenv('CALLAGENT_API_URL') . '/api-keys/scopes');
curl_setopt_array($handle, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('CALLAGENT_API_KEY'),
'Accept: application/json',
],
]);
$body = json_decode(curl_exec($handle), true);
$status = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);
if ($status >= 400) {
throw new RuntimeException("{$body['error']['type']}: {$body['error']['message']}");
}
$data = $body['data'];import os, requests
response = requests.get(
f"{os.environ['CALLAGENT_API_URL']}/api-keys/scopes",
headers={"Authorization": f"Bearer {os.environ['CALLAGENT_API_KEY']}"},
timeout=30,
)
response.raise_for_status()
data = response.json()["data"]Răspunsuri
| Status | Corp |
|---|---|
200 | data-wrapped array |
Exemplu de răspuns, generat din schemă:
{
"data": [
{
"group": "string",
"scopes": []
}
]
}