Skip to content

Api Key List

A list of API keys with their name, prefix, creation and last use, and scopes as badges. Create key opens a dialog with a name and scopes, then shows the secret once with a Copy button and a warning; it is never shown again. Revoke needs the key name typed to confirm. Your callbacks do the work. UI permission is not security: the server must check again.

Blockv0.1.0experimentalWCAG 2.2 AAView spec

A ready-made piece, built from the library's own parts.

A block puts several components together into something you would otherwise assemble by hand. It never fetches data: you give it the data, or answer its callbacks. It is copied into your project like any component, with the parts it uses, so you can change anything.

Basic

Full screen (opens in a new tab)

API keys

  • Deploy script

    Starts with rk_demo_8f2a…

    Created January 3, 2027 · Last used February 12, 2027

    • Read
    • Write
  • Reporting job

    Starts with rk_demo_c41d…

    Created November 9, 2026 · Never used

    • Read

States

Full screen (opens in a new tab)

API keys

API keys

No API keys yet

Create a key to call the API from your own code.

API keys

Couldn't load your API keys

Permissions

Full screen (opens in a new tab)

API keys

Only admins can create keys.

  • Deploy script

    Starts with rk_demo_8f2a…

    Created January 3, 2027 · Last used February 12, 2027

    • Read
    Only admins can revoke keys.

ClassNames

Full screen (opens in a new tab)

API keys

  • Deploy script

    Starts with rk_demo_8f2a…

    Created January 3, 2027 · Never used

    • Read
    • Write

Installation

npx rdloom add api-key-list

Copies the source into src/components/rdloom. Edit it freely: rdloom upgrade merges later versions into your changes.

Use another registry client
npx shadcn@latest add https://rdloom.vimalbhatt.com/r/api-key-list.json

Works, but without upgrade tracking.

Usage

import { ApiKeyList } from "@rdloom/react";

<div className="flex w-full justify-center">
  <div className="w-full max-w-3xl">
    <ApiKeyList
      keys={keys}
      scopes={scopes}
      onCreate={async (name, chosen) => {
        await wait(600);
        const secret = "rk_demo_4f9c2d71a8b34e5f9a60c1d2e3b4a5f6";
        setKeys((current) => [{ id: `k${current.length + 3}`, name, prefix: secret.slice(0, 12), scopes: chosen, createdAt: "2027-03-01", lastUsedAt: null }, ...current]);
        return { secret };
      }}
      onRevoke={async (key) => {
        await wait(500);
        setKeys((current) => current.filter((k) => k.id !== key.id));
      }}
    />
  </div>
</div>

API Reference

Defined by the spec. Components also accept the props of the React Aria component they wrap.

PropTypeDefault
keysrequired

The keys to list. prefix is the visible start of the key (never the secret). scopes are scope ids.

Array<{ id: string; name: string; prefix: string; scopes: string[]; createdAt: Date | string; lastUsedAt?: Date | string | null }>none
scopesrequired

The scopes a key can have, shown as checkboxes in the create dialog and as badges (by label) in the list.

Array<{ id: string; label: string; description?: string }>none
title

The heading of the list.

string"API keys"
headingLevel

Heading level of the title, 2 to 6.

number2
locale

The locale for dates.

string"en-US"
state

The data state: loading, empty (no keys, with Create key), error (with Try again) or ready. Without it an empty keys list shows the empty state.

DataStatenone
onRetry

Adds a Try again button to the error state.

() => voidnone
onCreaterequired

Creates the key on your server and resolves with its secret, which is shown once. A throw keeps the dialog open with an error.

(name: string, scopes: string[]) => Promise<{ secret: string }>none
onRevokerequired

Revokes the key after the person typed its name; yours, async.

(key: { id: string; name: string; prefix: string; scopes: string[]; createdAt: Date | string; lastUsedAt?: Date | string | null }) => void | Promise<unknown>none
permissions

What the app allows: create and revoke. Hidden renders nothing; disabled keeps the control reachable (aria-disabled) with the reason shown and read, and nothing runs. This only changes what people see: the server must check again.

Permissions<"create" | "revoke">none
classNames

Extra class names for single parts, so you can restyle one part without editing the file. Keys: root, header, title, createButton, list, item, name, prefix, meta, scopes, scope, revokeButton, dialog, form, secret, copyButton, warning, reason, status.

Partial<Record<"root" | "header" | "title" | "createButton" | "list" | "item" | "name" | "prefix" | "meta" | "scopes" | "scope" | "revokeButton" | "dialog" | "form" | "secret" | "copyButton" | "warning" | "reason" | "status", string>>none

Accessibility

Role list, WCAG 2.2 AA. Tested with axe and keyboard tests; screen reader checks are in the audit checklist.

Keyboard

  • Tab: moves through Create key and each Revoke button
  • In the create dialog: Tab moves through the name, the scopes, Cancel and Create key; Escape cancels
  • Revoke opens a confirmation where the key name is typed; Enter confirms once it matches

Screen readers announce

  • "API keys, heading level 2"
  • "Create key, button"; "Create API key, dialog"
  • "Copy this key now. You will not see it again."
  • "Key Deploy script revoked"

What your code must do

  • Keys are a list; each item names the key, its prefix, when it was created and last used, and its scopes
  • The create dialog asks for a name and at least one scope; problems go in an error summary linked to the fields
  • The secret is shown once, with a warning in words, and a Copy button that announces "Copied"
  • Closing the dialog removes the secret from the page; it cannot be shown again
  • Revoking needs the key name typed and is announced when done; focus then moves to the heading
  • A disabled action stays focusable and the reason is its description

Block contract

Data
The existing keys (without secrets), the available scopes, an async onCreate that returns the secret and an async onRevoke.
Data states
loading, empty, error, ready
Permissions
create, revoke
Events
onCreate, onRevoke, onRetry
You can replace
classNames for each part; scopes with descriptions; title and headingLevel; locale

Guidelines

Use it when

  • Letting people create and revoke the keys they use to call your API
  • A developer or integrations settings page

Avoid it when

  • Sessions or devices: use a list of sessions with a sign out action
  • Storing the secret: show it once and keep only a hash on your server

Don't

  • Treating the permissions prop as protection: UI permission is not security, so the server must check again
  • Keeping the secret in app state after the dialog closed: it is shown once on purpose
  • Putting the secret in the keys list: only the prefix belongs there

Design tokens

The semantic tokens this component uses. Change them once and every component follows; see Design tokens.

  • --rd-color-surface-default
  • --rd-color-surface-subtle
  • --rd-color-surface-raised
  • --rd-color-border-default
  • --rd-color-text-default
  • --rd-color-text-muted
  • --rd-color-feedback-warning
  • --rd-color-feedback-warning-subtle
  • --rd-color-feedback-danger
  • --rd-elevation-raised
  • --rd-elevation-overlay
  • --rd-radius-overlay