List the workspace's API keys
#!/usr/bin/env bashset -euo pipefailAPI=https://api.speccapture.comAUTH="Authorization: Bearer $SPECCAPTURE_API_KEY"
page=$(curl -sS --fail-with-body "$API/v1/api-keys" \ -H "$AUTH") || { echo "$page" >&2; exit 1; }
jq -r '.data[] as $key | "\($key.prefix)... \"\($key.name)\", a \($key.mode) key acting as \($key.role): \($key.status), last used \($key.lastUsedAt // "never")"' <<<"$page"using System.Text.Json;
using HttpClient http = new() { BaseAddress = new Uri("https://api.speccapture.com") };http.DefaultRequestHeaders.Authorization = new("Bearer", Environment.GetEnvironmentVariable("SPECCAPTURE_API_KEY"));
JsonElement page = await Json(await Call(HttpMethod.Get, "/v1/api-keys"));
foreach (JsonElement key in page.GetProperty("data").EnumerateArray()) { Console.WriteLine($"{key.GetProperty("prefix")}... \"{key.GetProperty("name")}\", a {key.GetProperty("mode")} key acting as {key.GetProperty("role")}: {key.GetProperty("status")}, last used {key.GetProperty("lastUsedAt").GetString() ?? "never"}");}
// Sends a request; stops with the problem's code and detail if the API refuses it.async Task<HttpResponseMessage> Call(HttpMethod method, string path, HttpContent? body = null, string? idempotencyKey = null) { using HttpRequestMessage request = new(method, path) { Content = body }; if (idempotencyKey is not null) request.Headers.Add("Idempotency-Key", idempotencyKey); HttpResponseMessage response = await http.SendAsync(request); if (!response.IsSuccessStatusCode) { JsonElement problem = await Json(response); string? detail = (problem.TryGetProperty("detail", out JsonElement text) ? text : problem.GetProperty("title")).GetString(); Console.Error.WriteLine($"{(int)response.StatusCode} {problem.GetProperty("code")}: {detail}"); Environment.Exit(1); } return response;}
// Reads an answer as JSON.static async Task<JsonElement> Json(HttpResponseMessage response) => JsonDocument.Parse(await response.Content.ReadAsStringAsync()).RootElement;import osimport sys
import requests
API = "https://api.speccapture.com"session = requests.Session()session.headers["Authorization"] = f"Bearer {os.environ['SPECCAPTURE_API_KEY']}"
def call(method, path, **kwargs): """Send a request; stop with the problem's code and detail if the API refuses it.""" response = session.request(method, API + path, **kwargs) if not response.ok: problem = response.json() sys.exit(f"{response.status_code} {problem['code']}: {problem.get('detail', problem['title'])}") return response
page = call("GET", "/v1/api-keys").json()
for key in page["data"]: print(f"{key['prefix']}... \"{key['name']}\", a {key['mode']} key acting as {key['role']}: {key['status']}, last used {key['lastUsedAt'] or 'never'}")const API = "https://api.speccapture.com";const headers = { Authorization: `Bearer ${process.env.SPECCAPTURE_API_KEY}` };
const page = await call("GET", "/v1/api-keys").then((response) => response.json());
for (const key of page.data) { console.log(`${key.prefix}... "${key.name}", a ${key.mode} key acting as ${key.role}: ${key.status}, last used ${key.lastUsedAt ?? "never"}`);}
// Sends a request; stops with the problem's code and detail if the API refuses it.async function call(method, path, init = {}) { const response = await fetch(API + path, { ...init, method, headers: { ...headers, ...init.headers } }); if (!response.ok) { const problem = await response.json(); console.error(`${response.status} ${problem.code}: ${problem.detail ?? problem.title}`); process.exit(1); } return response;}Every key the workspace has made, newest first: its name, prefix (its first characters, never the key), mode (live or test), the role it acts with, its rate limit, who made it, when it was made and last used, and its status - active, stopping (revoked with a grace period: it works until stopsAt) or revoked. Page with limit and cursor (the previous page’s nextCursor), narrow with createdAfter, createdBefore and status. Keys are made and revoked in the dashboard. A key acting as the workspace’s owner or an admin.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Query Parameters
Section titled “Query Parameters”How many items the page holds: 1 to 200, 50 when left out.
The previous page’s nextCursor, exactly as it came: the list continues just after that page’s last item, so items made or removed meanwhile never shift a page. Leave it out for the first page.
Only items made strictly after this date and time (ISO 8601, such as 2026-10-14T09:30:00Z; without an offset it is UTC).
Only items made strictly before this date and time (ISO 8601, such as 2026-10-14T09:30:00Z; without an offset it is UTC).
Only items with this status.
Responses
Section titled “Responses”OK
object
object
object
Bad Request: a problem with a stable code. See Errors for every code and what to do about it.
Every error: a problem with a stable code. https://speccapture.com/docs/api/errors lists every code.
object
A link to the code’s entry in the docs.
What went wrong, as a stable code to branch on: a published code never changes meaning.
This request’s trace: quote it when asking for help.
Forbidden: a problem with a stable code. See Errors for every code and what to do about it.
Every error: a problem with a stable code. https://speccapture.com/docs/api/errors lists every code.
object
A link to the code’s entry in the docs.
What went wrong, as a stable code to branch on: a published code never changes meaning.
This request’s trace: quote it when asking for help.