API Blocks
ApiBlock documents one REST endpoint in a single card from one typed
operation object: a color-coded method badge, the path, an auth indicator,
request parameters and body, a cURL command built from those values, and one or
more response tabs. Reach for Parameter Fields and
Response Fields when a field needs its own row
with a type and a default.
Quick Start
A GET endpoint with a summary and one response body.
/api/v1/statusCheck the service health status.
<ApiBlock
operation={{
method: 'GET',
path: '/api/v1/status',
summary: 'Check the service health status.',
responses: [
{
statusCode: '200',
exampleBody: '{"status":"healthy","uptime":99.97,"version":"1.0.0"}',
},
],
}}
/>Adding Options
Query and header parameters, a request body, bearer auth, and a rate limit with
a note. Watch the cURL command: the query parameter becomes ?expand=scope, the
header parameter becomes a -H flag, the bearer scheme adds an Authorization
header, and the JSON media types add Content-Type and Accept.
/api/v1/tokensBearer TokenGenerate an access token with a scope and expiration.
X-Idempotency-KeystringheaderrequiredexpandstringqueryDefault: scope<ApiBlock
operation={{
method: 'POST',
path: '/api/v1/tokens',
summary: 'Generate an access token with a scope and expiration.',
parameters: [
{
name: 'X-Idempotency-Key',
type: 'string',
location: 'header',
required: true,
description: 'Replay guard. Reuse the key to retry safely.',
},
{
name: 'expand',
type: 'string',
location: 'query',
defaultValue: 'scope',
description: 'Extra fields to inline in the response.',
},
],
requestBody: {
mediaType: 'application/json',
fields: [
{ name: 'scope', type: 'string', location: 'body', required: true },
{
name: 'expiresIn',
type: 'string',
location: 'body',
required: false,
defaultValue: '30d',
},
],
},
responses: [
{
statusCode: '201',
mediaType: 'application/json',
exampleBody:
'{"token":"eyJhbGciOi...","expiresAt":"2026-04-23T12:00:00Z"}',
},
],
auth: { scheme: 'bearer' },
}}
rateLimit={{ requests: 60, window: 'minute', note: 'per token' }}
/>Advanced
Two blocks cover the rest of the surface. The first pairs a deprecation warning with switchable response tabs, a base URL folded into the generated cURL, an auth label that overrides the scheme's default text, and a hand-written Python example that sits beside the generated cURL tab.
The second one drops summary so the card falls back to description, hides
the parameter panel with showParameters={false}, and marks the endpoint as
open with scheme: 'none', the one scheme that draws an open padlock instead of
a closed one. Its query and header parameters still reach the cURL command even
though no panel lists them, and the path parameter stays literal in the URL. The
204 response has no exampleBody, so only the status chip renders.
https://api.example.com/api/v1/docsAdmin tokenRetrieve documents using the legacy endpoint.
/api/v1/sessions/{sessionId}No auth requiredRevoke one session. This line comes from description, because the operation has no summary.
<ApiBlock
operation={{
method: 'GET',
path: '/api/v1/docs',
summary: 'Retrieve documents using the legacy endpoint.',
responses: [
{
statusCode: '200',
label: 'OK',
mediaType: 'application/json',
exampleBody: '{"items":[]}',
},
{
statusCode: '401',
label: 'Unauthorized',
exampleBody: '{"error":"invalid token"}',
},
],
auth: { scheme: 'bearer', label: 'Admin token' },
deprecated: true,
deprecationNote: 'Use GET /api/v1/documents instead.',
}}
baseUrl="https://api.example.com"
codeExamples={[
{
language: 'python',
label: 'Python',
code: 'import requests\n\nresponse = requests.get(\n "https://api.example.com/api/v1/docs",\n headers={"Authorization": "Bearer <token>"},\n)',
},
]}
/>
<ApiBlock
operation={{
method: 'DELETE',
path: '/api/v1/sessions/{sessionId}',
description:
'Revoke one session. This line comes from description, because the operation has no summary.',
parameters: [
{ name: 'sessionId', type: 'string', location: 'path', required: true },
{
name: 'reason',
type: 'string',
location: 'query',
defaultValue: 'user_logout',
},
{ name: 'X-Request-Id', type: 'string', location: 'header' },
],
responses: [{ statusCode: '204' }],
auth: { scheme: 'none' },
}}
showParameters={false}
/>Options
Props are validated with Zod at render time. An invalid shape throws with the exact field path in the message rather than rendering an empty card.
Component props
operationobjectrequiredThe endpoint's data as one object — a subset of the EndpointOperation type
from lib/openapi-import/types.ts, so anything the OpenAPI importer produces
can be passed straight through.
baseUrlstringPrefix shown in muted text before the path and prepended to the cURL URL.
rateLimitobjectRate-limit line under the summary, with a clock icon.
codeExamplesarrayExtra request examples. They appear as tabs after the generated cURL tab, which is always first and can't be removed.
showParametersbooleanDefault: trueSet false when the surrounding page renders its own parameter documentation,
as components/OpenApiEmbed.tsx does. Hiding the panel does not change the
generated cURL.
operation
operation.methodstringrequiredGET, POST, PUT, PATCH, or DELETE. Sets the badge color and the left
border color: blue, green, amber, purple, red.
operation.pathstringrequiredThe URL path shown next to the badge and used in the cURL command. Must be at least one character. Path placeholders are copied through as written.
operation.summarystringText shown below the header explaining what the endpoint does. Wins over
operation.description when both are set.
operation.descriptionstringFallback body text used when operation.summary is absent. Rendered as plain
text, so Markdown in it stays literal.
operation.parametersarrayDefault: []Request parameters. Query and header entries render as ParamField rows and
feed the cURL query string and -H flags. Path and body entries are accepted
for importer parity but render nothing and don't rewrite the URL.
operation.requestBodyobjectThe request payload description and the source of the cURL -d flag.
operation.responsesarrayDefault: []One entry per documented status code. Two or more render as clickable tabs.
operation.authobjectDefault: {}Auth indicator in the top-right corner of the header.
operation.deprecatedbooleanDefault: falseAdds a red "Deprecated" chip and fades the card to 75% opacity.
operation.deprecationNotestringMigration guidance shown in a red warning box above the summary. It renders on
its own, so a note without deprecated: true still shows the box.
operation.parameters entries
namestringrequiredParameter name. Header parameters use this as the literal header name in the generated cURL.
typestringType label shown in the chip next to the name.
locationstringrequiredOne of path, query, header, or body.
requiredbooleanDefault: falseAdds the red "required" label to the row.
defaultValuestringShown as Default: on the row and used as the sample value in the cURL
command. Without it, the cURL falls back to <name>.
deprecatedbooleanStrikes through the parameter name and dims the row.
descriptionstringRow description, rendered as inline Markdown. Rows without one read "No description provided."
operation.requestBody
mediaTypestringDefault: application/jsonValue sent as the Content-Type header in the generated cURL.
examplestringLiteral payload for the cURL -d flag. Without it, the flag gets a skeleton
built from fields.
descriptionstringAccepted for importer parity. The card does not render it today.
fieldsarrayDefault: []Body fields, using the same shape as operation.parameters. The Request Body
panel prefers example when it's set; with no example, it falls back to
pretty-printing fields as JSON, and shows nothing at all if both are empty.
operation.responses entries
statusCodestringrequiredDrives the chip color: green for 2xx, blue for 3xx, amber for 4xx, red for everything else.
labelstringExtra text on the tab button, such as Unauthorized. Only visible when the
operation has two or more responses.
descriptionstringAccepted for importer parity. The card does not render it today.
mediaTypestringWhen any response media type contains json, the generated cURL gains an
Accept: application/json header.
exampleBodystringJSON-encoded response body. It's re-indented before highlighting, and invalid JSON is printed as-is. Leave it out and only the status chip renders.
fieldsarrayDefault: []Accepted so importer output passes through unchanged. Document response shapes with Response Fields instead.
headersarrayDefault: []Response headers as { name, type, description }. Accepted for importer
parity; the card does not render them today.
operation.auth
schemestringbearer, apiKey, basic, oauth2, or none. The first four add the
matching placeholder header to the cURL command and a closed padlock; none
shows an open padlock and adds no header.
labelstringOverrides the default text — "Bearer Token", "API Key", "Basic Auth", "OAuth 2.0", or "No auth required".
descriptionstringAccepted for importer parity. The card does not render it today.
rateLimit
requestsnumberrequiredThe request count, printed before the slash.
windowstringrequiredThe window the count applies to, printed after the slash: minute, hour,
10 seconds.
notestringQualifier appended in parentheses, such as "per token".
codeExamples entries
languagestringrequiredHighlighting grammar. bash and python are loaded; any other value falls
back to the JSON grammar.
labelstringrequiredTab label.
codestringrequiredExample source. The copy button copies whichever tab is active.