curl --request GET \
--url https://api.farthing.ai/v1/api-keys \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.farthing.ai/v1/api-keys"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.farthing.ai/v1/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://api.farthing.ai/v1/api-keys",
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://api.farthing.ai/v1/api-keys"
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://api.farthing.ai/v1/api-keys")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.farthing.ai/v1/api-keys")
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{
"data": [
{
"id": "2a44c7f0-1b23-4a95-9d0e-77e1b6c4a812",
"label": "agent for user_a91f",
"mode": "live",
"scopes": [
"checkouts.write"
],
"subject": "user_a91f",
"keyPrefix": "ck_live_9Hf2QzT",
"lastUsedAt": "2026-07-29T09:14:31.190Z",
"revokedAt": null,
"createdAt": "2026-07-29T09:02:10.771Z"
},
{
"id": "8b7c6d5e-4f30-4a21-9b8c-0d1e2f3a4b5c",
"label": "ci",
"mode": "test",
"scopes": [
"*"
],
"subject": null,
"keyPrefix": "ck_test_3sQd7yQ",
"lastUsedAt": null,
"revokedAt": "2026-07-27T11:44:09.331Z",
"createdAt": "2026-07-20T08:15:02.640Z"
}
],
"keys": [
{
"id": "2a44c7f0-1b23-4a95-9d0e-77e1b6c4a812",
"label": "agent for user_a91f",
"mode": "live",
"scopes": [
"checkouts.write"
],
"subject": "user_a91f",
"keyPrefix": "ck_live_9Hf2QzT",
"lastUsedAt": "2026-07-29T09:14:31.190Z",
"revokedAt": null,
"createdAt": "2026-07-29T09:02:10.771Z"
},
{
"id": "8b7c6d5e-4f30-4a21-9b8c-0d1e2f3a4b5c",
"label": "ci",
"mode": "test",
"scopes": [
"*"
],
"subject": null,
"keyPrefix": "ck_test_3sQd7yQ",
"lastUsedAt": null,
"revokedAt": "2026-07-27T11:44:09.331Z",
"createdAt": "2026-07-20T08:15:02.640Z"
}
],
"nextCursor": null
}List API keys
Answers { data, keys, nextCursor }: data is the field the checkout and buyer-profile lists also use and the one to read, keys is the same array under its original name, and nextCursor is always null because this collection is not paged. Newest first. Revoked keys are included, with revokedAt set — filter client-side if you only want active ones.
Listing never returns a secret. keyPrefix is the most a list can show.
Requires the api-keys.read scope.
A subject-bound key cannot call this: the key list is a tenant-wide fact, and a credential acting for one end user must not be able to enumerate its siblings. 403.
curl --request GET \
--url https://api.farthing.ai/v1/api-keys \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.farthing.ai/v1/api-keys"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.farthing.ai/v1/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://api.farthing.ai/v1/api-keys",
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://api.farthing.ai/v1/api-keys"
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://api.farthing.ai/v1/api-keys")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.farthing.ai/v1/api-keys")
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{
"data": [
{
"id": "2a44c7f0-1b23-4a95-9d0e-77e1b6c4a812",
"label": "agent for user_a91f",
"mode": "live",
"scopes": [
"checkouts.write"
],
"subject": "user_a91f",
"keyPrefix": "ck_live_9Hf2QzT",
"lastUsedAt": "2026-07-29T09:14:31.190Z",
"revokedAt": null,
"createdAt": "2026-07-29T09:02:10.771Z"
},
{
"id": "8b7c6d5e-4f30-4a21-9b8c-0d1e2f3a4b5c",
"label": "ci",
"mode": "test",
"scopes": [
"*"
],
"subject": null,
"keyPrefix": "ck_test_3sQd7yQ",
"lastUsedAt": null,
"revokedAt": "2026-07-27T11:44:09.331Z",
"createdAt": "2026-07-20T08:15:02.640Z"
}
],
"keys": [
{
"id": "2a44c7f0-1b23-4a95-9d0e-77e1b6c4a812",
"label": "agent for user_a91f",
"mode": "live",
"scopes": [
"checkouts.write"
],
"subject": "user_a91f",
"keyPrefix": "ck_live_9Hf2QzT",
"lastUsedAt": "2026-07-29T09:14:31.190Z",
"revokedAt": null,
"createdAt": "2026-07-29T09:02:10.771Z"
},
{
"id": "8b7c6d5e-4f30-4a21-9b8c-0d1e2f3a4b5c",
"label": "ci",
"mode": "test",
"scopes": [
"*"
],
"subject": null,
"keyPrefix": "ck_test_3sQd7yQ",
"lastUsedAt": null,
"revokedAt": "2026-07-27T11:44:09.331Z",
"createdAt": "2026-07-20T08:15:02.640Z"
}
],
"nextCursor": null
}Authorizations
Authorization: Bearer ck_test_… or ck_live_…. There is no other auth scheme — no query-string keys, no request signing, no OAuth.
Response
Every key on the tenant, newest first, revoked ones included. Not paged.
The collection. Read this one — it is the field the checkout and buyer-profile lists answer with too. (GET /v1/buyer-sessions is the one list route that has not converged: it answers { sessions, vaultEnabled }.)
Show child attributes
Show child attributes
The same array under the field's original name, kept because existing callers read it. Identical contents; prefer data in new code.
Show child attributes
Show child attributes
Always null here — the collection is small and tenant-bounded, so there is nothing to page. Present so a generic list client needs no special case.