Skip to content

API

The public API

Everything the website knows, over HTTP. No key, no account, no rate limit worth documenting — the catalog is already fully indexed by search engines, so gating it would only break the tools that use it.

Basics

Basehttps://hoverlab5.netlify.app/api/v1
AuthNone. Do not send credentials.
CORSOpen (*) — callable from a browser
MethodsGET and OPTIONS

Endpoints

Each tier has the same pair — a list endpoint that searches, and a detail endpoint that returns source. The five below them do not follow that shape, because none of them is a tier: they answer across the catalog rather than within one rung of it.

EndpointReturns
GET /api/v1/effectsSearch effects — metadata only
GET /api/v1/effects/{id}One effect, with HTML + CSS
GET /api/v1/blocksSearch blocks
GET /api/v1/blocks/{id}One block, with its source files
GET /api/v1/pagesSearch pages
GET /api/v1/pages/{id}One page, with its files
GET /api/v1/templatesSearch templates
GET /api/v1/templates/{id}One template, with every file
GET /api/v1/artifacts/{id}Resolves an id against all four tiers — use this when you do not know the tier
GET /api/v1/dna/{id}Design DNA — the tokens and rules as a document for an AI tool. Takes any id, or "catalog"
GET /api/v1/skillsThe agent skills this catalog publishes
GET /api/v1/skills/{id}One skill; add ?format=raw for the markdown itself
GET /api/v1/kitsThe curated cross-tier sets; add ?slug= for one kit’s full contents and its install line
GET /api/v1/trendingWhat has actually been copied and installed this week. Empty is a normal answer
GET /api/v1/revisionsWhat changed and when, per artifact — the update ledger behind the changelog

Fetching source

Detail responses carry the files at the paths they should be written to, so a client can write them out without knowing anything about the tier it asked for.

terminal
curl "https://hoverlab5.netlify.app/api/v1/artifacts/pricing-tiers"
response (trimmed)
{
  "version": "v1",
  "level": "block",
  "artifact": { "id": "pricing-tiers", "name": "…", "fileCount": 1, … },
  "files": [
    { "path": "components/pricing-tiers.tsx", "lang": "tsx", "source": "…" }
  ],
  "deps": ["lucide-react"],
  "notes": ["…"],
  "included": []
}

Add deep=true to a page or template to pull in everything it is composed of — the ids that came along appear in included.

terminal
curl "https://hoverlab5.netlify.app/api/v1/pages/checkout-page?deep=true"

Effects in other frameworks

An effect is markup plus a stylesheet, so it can be handed to any framework without losing anything. Pass framework to the effect detail endpoint.

terminal
curl "https://hoverlab5.netlify.app/api/v1/effects/btn-gradient?framework=vue"

Valid values: html, css, react, vue, svelte, styled-components, tailwind. The customization knobs work here too — hue, sat, scale, speed.

Motion-safety profile

Every effect response carries a motion object: four checks on the effect's shipped CSS, computed for the whole catalog and re-verified at build. It is the same data as the panel on the effect page.

terminal
curl "https://hoverlab5.netlify.app/api/v1/effects/btn-gradient" | jq .motion
response
{
  "applicable": true,
  "animates": true,
  "reducedMotion": "brief",
  "propertyClass": "paint",
  "offending": ["background-position", "box-shadow"],
  "flash": { "verdict": "pass", "hz": null },
  "layoutShift": "none"
}
FieldValues
reducedMotionguarded ships a prefers-reduced-motion block; brief animates but does not loop, so no guard ships; unguarded loops with no guard; none does not animate. The same predicate the catalog's motion audit uses.
propertyClassWorst wins: compositor (transform, opacity, filter), paint (colour, background, shadow, clip-path), layout (width, height, top/left, margin, padding), none. offending lists the non-compositor properties, layout ones first.
flashverdict is pass, caution or fail against WCAG 2.3.1 (three flashes a second). hz is the highest estimated rate, or null when nothing alternates brightness. fail needs a repeating change above 3 Hz that is both strong and plainly large.
layoutShiftshifts when propertyClass is layout, otherwise none. A category, not a number.
measuredPresent only on the effects that were run in Chromium: cls, entries and the windowSeconds it covers. The only numeric layout-shift figure in the response.
Everything but measured is a static estimate read from the CSS text, not a rendering test. The flash rate is an upper bound from duration, iterations and keyframe alternation, and it does not know what is behind the effect. The profile describes the effect as published; the speed knob retimes it, so recheck a customized copy. Canvas and WebGL effects return { "applicable": false, "reason": "…" }, and effects that are not in the catalog return null.

Blocks outside React

There is no framework param for blocks, and that is deliberate. A block is hundreds of lines of React with hooks and event handlers; a machine translation of it would be a worse block claiming to be the same one.

What you can have is the block rendered to HTML. Tailwind classes are framework-agnostic, so the design transfers intact even though the component does not.

terminal
curl "https://hoverlab5.netlify.app/api/v1/blocks/pricing-tiers?format=html"
The response is one frame: the component in its initial state with the handlers gone. For an interactive block — a navbar with a mobile menu, a form with pending state — you get the closed, idle markup and re-wire the behaviour yourself. The notes array says so on every response.

Caching

An effect id always resolves to the same CSS, so those responses are cacheable indefinitely. Block, page and template source is hand-written and gets fixed, so it carries a shorter edge cache — an accessibility fix should reach the next install, not a year later.

Something wrong or missing here? Browse the catalog — every page in it links back to the source it documents.