API keys for live and test, a new key's secret shown once as its characters settle, revoking behind a hold, and webhooks: each endpoint with its recent deliveries, events and signing secret, a test event that lands in the log, deliveries opened with their payload and retried in place. On motion.
Installation
When to use
- The developer page of a product with an API: keys for live and test, and webhooks with their deliveries.
- Products where customers build on you and need to make keys, test their endpoints and see why a delivery failed.
When not to use
- Personal access tokens in a profile: a short list in Profile settings is enough.
- Watching API traffic over time: a dashboard with charts fits better.
Usage
Developer settings with your own data: every prop has the sample as its default, so pass only what you have.
"use client"
import { DeveloperSettings } from "@/components/dashral/blocks/developer-settings"
export default function Developers() {
return (
<DeveloperSettings
keys={[{ id: "k1", name: "Production server", environment: "live", scope: "full", last4: "8f2a", created: "Mar 2, 2026", lastUsed: "2 minutes ago" }]}
endpoints={[{ id: "e1", url: "https://api.acme.com/webhooks", events: ["invoice.paid"], status: "active", secretLast4: "a7f1", environment: "live" }]}
deliveries={[]}
history={{}}
// Return the key with its full secret: it's shown once.
onCreateKey={async (input) => {
const secret = `sk_${input.environment}_${crypto.randomUUID().replaceAll("-", "")}`
return { key: { id: crypto.randomUUID(), name: input.name, environment: input.environment, scope: input.scope, scopes: input.scopes, last4: secret.slice(-4), created: "Just now" }, secret }
}}
onRevokeKey={async (key) => console.log("revoke", key.id)}
// Send the event to the endpoint and return the delivery as it went.
onSendTest={async (endpoint, event) => ({ id: crypto.randomUUID(), endpointId: endpoint.id, event, status: 200, duration: 120, time: "Just now" })}
/>
)
}API reference
DeveloperSettings
Developer settings: API keys for live and test (create one and see its secret once, revoke behind a hold), and webhooks (each endpoint with its recent deliveries, events and signing secret, a test event, and the delivery log, a delivery opened with its payload and response, retried in place). Every change calls your handler first.
| Prop | Type | Default |
|---|---|---|
title | React.ReactNode | "Developers" |
keys | DeveloperKey[] | sample |
endpoints | WebhookEndpoint[] | sample |
deliveries | WebhookDelivery[] | sample |
history | Record<string, boolean[]>Each endpoint's recent deliveries, oldest first: true went through. | sample |
events | string[]The events an endpoint can listen to. | sample |
keyScopes | string[]The permissions a restricted key can be given. | sample |
onCreateKey | (input: NewKeyInput) => Promise<{ key: DeveloperKey; secret: string }> | { key: DeveloperKey; secret: string }Make a key: return it with its full secret, shown once. Left out, a secret is made in the browser. While the promise is pending Create shows it; a thrown Error's message shows in the dialog. | — |
onRevokeKey | (key: DeveloperKey) => Promise<void> | voidRevoke after the hold: the dialog waits for the promise; a throw keeps the key and says why. | — |
onSendTest | (endpoint: WebhookEndpoint, event: string) => Promise<WebhookDelivery> | WebhookDeliverySend a test event: return the delivery as it went (its status). While pending it shows on its way in the log. | — |
onRetry | (delivery: WebhookDelivery) => Promise<WebhookDelivery> | WebhookDeliverySend a delivery again: return the new attempt. | — |
onEndpointEvents | (endpoint: WebhookEndpoint, events: string[]) => Promise<void> | voidAn endpoint's events changed: shown at once, put back if this throws. | — |
onRevealSecret | (endpoint: WebhookEndpoint) => Promise<string> | stringShow a signing secret: return it whole (only its last four are kept here). | — |
className | string | — |
type KeyEnvironment
= "live" | "test"type KeyScope
= "full" | "read" | "restricted"type DeveloperKey
| Prop | Type | Default |
|---|---|---|
id | string | — |
name | string | — |
environment | KeyEnvironment | — |
scope | KeyScope | — |
scopes | string[]For a restricted key: what it may do ("customers:read"…). | — |
last4 | stringThe secret's last four characters, all that's kept. | — |
created | string | — |
lastUsed | string | — |
type WebhookEndpoint
| Prop | Type | Default |
|---|---|---|
id | string | — |
url | string | — |
description | string | — |
events | string[] | — |
status | "active" | "failing" | "disabled" | — |
secretLast4 | stringThe signing secret's last four characters. | — |
environment | KeyEnvironment | — |
type WebhookDelivery
| Prop | Type | Default |
|---|---|---|
id | string | — |
endpointId | string | — |
event | string | — |
status | number | nullThe HTTP status your endpoint answered with; null while it's on its way. | — |
duration | numberIn milliseconds. | — |
time | string | — |
payload | unknown | — |
response | string | — |
type NewKeyInput
| Prop | Type | Default |
|---|---|---|
name | string | — |
environment | KeyEnvironment | — |
scope | KeyScope | — |
scopes | string[] | — |