API-first integrations
A valid request sample and an endpoint list instead of a partner wall.
Live preview
Source
This exact file renders the preview above.
import { ArrowRight, Webhook } from 'lucide-react'
import { ButtonLink } from '@/components/ui/button'
import { Container } from '@/components/ui/layout'
import { Badge } from '@/components/ui/badge'
/**
* API-first integration section
*
* For products whose real integration story is "there is an API". A short,
* valid request sample is more convincing than a wall of partner logos, and
* the endpoint list tells an evaluator the shape of the surface in ten seconds.
*/
const endpoints = [
{ method: 'GET', path: '/v1/components', description: 'List catalogue items with filters' },
{
method: 'GET',
path: '/v1/components/{slug}',
description: 'One item with source and relations',
},
{ method: 'POST', path: '/v1/exports', description: 'Generate a token export' },
{ method: 'GET', path: '/v1/events', description: 'Server-sent stream of catalogue changes' },
]
const sample = `curl https://api.foundry.example/v1/components \\
-H "Authorization: Bearer $FOUNDRY_TOKEN" \\
-G --data-urlencode "category=overlay"`
export default function ApiFirstIntegrations() {
return (
<section className="border-b border-line bg-canvas py-section">
<Container>
<div className="grid gap-10 lg:grid-cols-2 lg:gap-16">
<div>
<Badge tone="accent" icon={<Webhook className="size-3" />}>
API first
</Badge>
<h2 className="display-type mt-4 text-2xl font-semibold text-ink-strong sm:text-3xl">
Everything in the catalogue is addressable.
</h2>
<p className="mt-4 max-w-lg text-md text-ink-muted">
A fictional REST surface, documented the same way the components are. Tokens, sources
and relations are all queryable.
</p>
<div className="mt-7 overflow-hidden rounded-xl border border-line bg-code-surface">
<div className="border-b border-white/10 px-4 py-2">
<span className="font-mono text-2xs text-white/50">Request</span>
</div>
<pre className="thin-scrollbar overflow-x-auto p-4 font-mono text-xs leading-relaxed text-code-ink">
<code>{sample}</code>
</pre>
</div>
<ButtonLink
href="/starters/documentation/preview/api"
variant="outline"
className="mt-6"
trailingIcon={<ArrowRight className="size-4" />}
>
Read the API reference
</ButtonLink>
</div>
<div>
<h3 className="label-caps text-ink-subtle">Endpoints</h3>
<ul className="mt-4 divide-y divide-[var(--color-border-subtle)] rounded-xl border border-line bg-surface">
{endpoints.map((endpoint) => (
<li
key={endpoint.path}
className="flex flex-wrap items-baseline gap-x-3 gap-y-1 p-4"
>
<Badge
size="sm"
appearance="solid"
tone={endpoint.method === 'GET' ? 'info' : 'success'}
className="font-mono"
>
{endpoint.method}
</Badge>
<code className="min-w-0 font-mono text-xs break-token text-ink-strong">
{endpoint.path}
</code>
<span className="w-full text-xs text-ink-muted">{endpoint.description}</span>
</li>
))}
</ul>
</div>
</div>
</Container>
</section>
)
}
components/blocks/sections/integrations/api-first.tsx
import { ArrowRight, Webhook } from 'lucide-react'
import { ButtonLink } from '@/components/ui/button'
import { Container } from '@/components/ui/layout'
import { Badge } from '@/components/ui/badge'
/**
* API-first integration section
*
* For products whose real integration story is "there is an API". A short,
* valid request sample is more convincing than a wall of partner logos, and
* the endpoint list tells an evaluator the shape of the surface in ten seconds.
*/
const endpoints = [
{ method: 'GET', path: '/v1/components', description: 'List catalogue items with filters' },
{
method: 'GET',
path: '/v1/components/{slug}',
description: 'One item with source and relations',
},
{ method: 'POST', path: '/v1/exports', description: 'Generate a token export' },
{ method: 'GET', path: '/v1/events', description: 'Server-sent stream of catalogue changes' },
]
const sample = `curl https://api.foundry.example/v1/components \\
-H "Authorization: Bearer $FOUNDRY_TOKEN" \\
-G --data-urlencode "category=overlay"`
export default function ApiFirstIntegrations() {
return (
<section className="border-b border-line bg-canvas py-section">
<Container>
<div className="grid gap-10 lg:grid-cols-2 lg:gap-16">
<div>
<Badge tone="accent" icon={<Webhook className="size-3" />}>
API first
</Badge>
<h2 className="display-type mt-4 text-2xl font-semibold text-ink-strong sm:text-3xl">
Everything in the catalogue is addressable.
</h2>
<p className="mt-4 max-w-lg text-md text-ink-muted">
A fictional REST surface, documented the same way the components are. Tokens, sources
and relations are all queryable.
</p>
<div className="mt-7 overflow-hidden rounded-xl border border-line bg-code-surface">
<div className="border-b border-white/10 px-4 py-2">
<span className="font-mono text-2xs text-white/50">Request</span>
</div>
<pre className="thin-scrollbar overflow-x-auto p-4 font-mono text-xs leading-relaxed text-code-ink">
<code>{sample}</code>
</pre>
</div>
<ButtonLink
href="/starters/documentation/preview/api"
variant="outline"
className="mt-6"
trailingIcon={<ArrowRight className="size-4" />}
>
Read the API reference
</ButtonLink>
</div>
<div>
<h3 className="label-caps text-ink-subtle">Endpoints</h3>
<ul className="mt-4 divide-y divide-[var(--color-border-subtle)] rounded-xl border border-line bg-surface">
{endpoints.map((endpoint) => (
<li
key={endpoint.path}
className="flex flex-wrap items-baseline gap-x-3 gap-y-1 p-4"
>
<Badge
size="sm"
appearance="solid"
tone={endpoint.method === 'GET' ? 'info' : 'success'}
className="font-mono"
>
{endpoint.method}
</Badge>
<code className="min-w-0 font-mono text-xs break-token text-ink-strong">
{endpoint.path}
</code>
<span className="w-full text-xs text-ink-muted">{endpoint.description}</span>
</li>
))}
</ul>
</div>
</div>
</Container>
</section>
)
}
components/ui/badge.tsx
import type { HTMLAttributes, ReactNode } from 'react'
import { variants } from '@/lib/variants'
/**
* Badge
*
* A compact, non-interactive label. Tones map to the status token trios, and
* because a badge is often the only signal in a dense table, the `dot` option
* exists to add a second, colour-independent cue alongside the text.
*/
const badgeVariants = variants('inline-flex items-center gap-1.5 whitespace-nowrap font-medium', {
variants: {
tone: {
neutral: 'bg-surface-sunken text-ink-muted border-line',
accent: 'bg-accent-soft text-accent-soft-ink border-accent-line',
success: 'bg-success-soft text-success border-success-line',
warning: 'bg-warning-soft text-warning border-warning-line',
danger: 'bg-danger-soft text-danger border-danger-line',
info: 'bg-info-soft text-info border-info-line',
inverse: 'bg-surface-inverse text-ink-inverse border-transparent',
},
appearance: {
soft: 'border',
outline: 'border bg-transparent',
solid: 'border border-transparent',
},
size: {
sm: 'h-4.5 rounded-sm px-1.5 text-2xs',
md: 'h-5.5 rounded-sm px-2 text-xs',
},
},
defaultVariants: { tone: 'neutral', appearance: 'soft', size: 'md' },
compound: [
{ appearance: 'solid', tone: 'accent', class: 'bg-accent text-accent-ink' },
{ appearance: 'solid', tone: 'success', class: 'bg-success text-white' },
{ appearance: 'solid', tone: 'warning', class: 'bg-warning text-white' },
{ appearance: 'solid', tone: 'danger', class: 'bg-danger text-white' },
{ appearance: 'solid', tone: 'info', class: 'bg-info text-white' },
{ appearance: 'solid', tone: 'neutral', class: 'bg-ink text-ink-inverse' },
{ appearance: 'outline', tone: 'neutral', class: 'text-ink-muted' },
],
})
export type BadgeTone = 'neutral' | 'accent' | 'success' | 'warning' | 'danger' | 'info' | 'inverse'
export interface BadgeProps extends HTMLAttributes<HTMLSpanElement> {
tone?: BadgeTone
appearance?: 'soft' | 'outline' | 'solid'
size?: 'sm' | 'md'
/** Adds a leading dot so the badge does not rely on hue alone. */
dot?: boolean
icon?: ReactNode
}
export function Badge({
tone = 'neutral',
appearance = 'soft',
size = 'md',
dot = false,
icon,
className,
children,
...props
}: BadgeProps) {
return (
<span className={badgeVariants({ tone, appearance, size, className })} {...props}>
{dot ? (
<span className="size-1.5 shrink-0 rounded-full bg-current" aria-hidden="true" />
) : null}
{icon}
{children}
</span>
)
}
Demo source — adapt to your project. Foundry is not published as a package.
Usage
For products whose real integration story is 'there is an API'. A short, valid request is more convincing than a wall of partner logos.
- The sample must actually be runnable in shape, even against a fictional host.
- Show the response shape or link to it; an endpoint list alone is half the answer.
Variants and states
Every entry below is a genuine difference in behaviour or layout, and every one of them is visible in the preview above.
- Request sample
- Four endpoints
- Method badges
Accessibility
- Selectable code
- The sample is a pre element, not an image.
- Method badges
- HTTP methods are text in a badge, readable by assistive tech.
Foundry implements published ARIA patterns and is tested against them. No WCAG certification is claimed — see the accessibility documentation for what is and is not covered.
Related
All sectionsCode-sample hero
A developer hero pairing the pitch with a real, valid code sample in a window frame.
starterFeatured3 variantsDocumentation starter
A developer documentation site with six article routes, a guide index, an API reference and a working search page.
intermediateFeatured4 variantsFeatured integrations
Two integrations given real explanation instead of twelve given none.
starter3 variants