Skip to main content
Context.dev’s Styleguide API returns a website’s full styleguide:
  • mode: light or dark
  • colors: accent, background, text (hex)
  • typography: detected headings (h1h4) and p with fontFamily, fontFallbacks, fontSize, fontWeight, lineHeight, letterSpacing
  • elementSpacing: xs, sm, md, lg, xl
  • shadows: sm, md, lg, xl, inner
  • components: detected button variants (primary, secondary, link) and card with full computed CSS
  • fontLinks: Google or @font-face font files keyed by family, with downloadable URLs per weight
A separate fonts-only endpoint returns the typography subset for a fraction of the cost.

Integrate Context.dev's Design System API in your app

Open in Cursor

Prerequisites

  • A Context.dev API key. Sign up at context.dev/signup, copy the key from the dashboard (prefix ctxt_secret_), and export it:
    export CONTEXT_DEV_API_KEY="ctxt_secret_..."
    
  • An SDK (optional). Install for your language, or skip the install and call directly with curl:
    npm install context.dev
    

Extract the full styleguide

GET /web/styleguide takes in a domain (or a webpage URL) and returns the website’s full design system.
curl -G https://api.context.dev/v1/web/styleguide \
  -H "Authorization: Bearer $CONTEXT_DEV_API_KEY" \
  --data-urlencode "domain=vercel.com"
10 credits per successful call

Request Parameters

Either domain or directUrl must be provided, but not both.
ParameterTypeDescription
domainstringDomain to extract the styleguide from (e.g. vercel.com).
directUrlstringA specific URL to fetch the styleguide from directly, bypassing domain resolution (e.g. https://stripe.com/pricing).
maxAgeMsintegerMax cache age before a hard refresh. Defaults to 7776000000 (90 days). Clamped to [86400000, 31536000000] (1 day – 1 year).
timeoutMSinteger (1000–300000)Abort with a 408 if the request exceeds this many milliseconds. Max 300000 (5 min).

Response

{
  "status": "ok",
  "domain": "vercel.com",
  "code": 200,
  "styleguide": {
    "mode": "light",
    "colors": {
      "accent": "#000000",
      "background": "#fafafa",
      "text": "#171717"
    },
    "typography": {
      "headings": {
        "h1": {
          "fontFamily": "Geist",
          "fontFallbacks": ["Geist", "Arial", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"],
          "fontSize": "35px",
          "fontWeight": 600,
          "lineHeight": "46.0687px",
          "letterSpacing": "-1.945px"
        }
      },
      "p": {
        "fontFamily": "Geist",
        "fontFallbacks": ["Geist", "Arial", "system-ui", "-apple-system", "Segoe UI", "Roboto", "Helvetica Neue", "sans-serif"],
        "fontSize": "16px",
        "fontWeight": 400,
        "lineHeight": "24px",
        "letterSpacing": "0px"
      }
    },
    "elementSpacing": {
      "xs": "2px",
      "sm": "6px",
      "md": "16px",
      "lg": "22px",
      "xl": "40px"
    },
    "shadows": {
      "sm": "rgba(0, 0, 0, 0.08) 0px 0px 0px 1px, rgba(0, 0, 0, 0.04) 0px 2px 2px 0px, rgba(0, 0, 0, 0.04) 0px 8px 8px -8px",
      "md": "none",
      "lg": "none",
      "xl": "none",
      "inner": "none"
    },
    "fontLinks": {
      "Geist": {
        "type": "google",
        "category": "sans-serif",
        "files": {
          "400": "https://fonts.gstatic.com/s/geist/v4/gyBhhwUxId8gMGYQMKR3pzfaWI_RnOM4nZPby1QNtA.ttf",
          "500": "https://fonts.gstatic.com/s/geist/v4/gyBhhwUxId8gMGYQMKR3pzfaWI_RruM4nZPby1QNtA.ttf",
          "600": "https://fonts.gstatic.com/s/geist/v4/gyBhhwUxId8gMGYQMKR3pzfaWI_RQuQ4nZPby1QNtA.ttf",
          "700": "https://fonts.gstatic.com/s/geist/v4/gyBhhwUxId8gMGYQMKR3pzfaWI_Re-Q4nZPby1QNtA.ttf"
        }
      }
    },
    "components": {
      "button": {
        "primary": {
          "backgroundColor": "#171717",
          "color": "#ffffff",
          "borderColor": "#ffffff",
          "borderRadius": "100px",
          "borderWidth": "0px",
          "borderStyle": "none",
          "padding": "13px 14px",
          "minWidth": "181px",
          "minHeight": "40px",
          "fontFamily": "Geist",
          "fontSize": "14px",
          "fontWeight": 500,
          "textDecoration": "none",
          "boxShadow": "none",
          "css": "background-color: #171717; color: #ffffff; border-radius: 100px; padding: 13px 14px; font-family: Geist; font-size: 14px; font-weight: 500;"
        }
      },
      "card": {
        "backgroundColor": "#fafafa",
        "textColor": "#171717",
        "borderColor": "#e5e7eb",
        "borderRadius": "8px",
        "borderWidth": "1px",
        "borderStyle": "solid",
        "padding": "16px",
        "boxShadow": "none",
        "css": "background-color: #fafafa; color: #171717; border: 1px solid #e5e7eb; border-radius: 8px; padding: 16px;"
      }
    }
  }
}
FieldTypeDescription
statusstring"ok" on success.
domainstringNormalized domain that was processed.
codeintegerHTTP status code.
styleguide.modestring"light" or "dark": the page’s primary color mode.
styleguide.colorsobjectaccent, background, text: all hex strings.
styleguide.typography.headingsobjecth1, h2, h3, h4: each has fontFamily, fontFallbacks[], fontSize, fontWeight, lineHeight, letterSpacing.
styleguide.typography.pobjectBody text: same shape as a heading entry.
styleguide.elementSpacingobjectxs, sm, md, lg, xl: CSS length strings (typically px).
styleguide.shadowsobjectsm, md, lg, xl, inner: full box-shadow declarations. "none" when no shadow at that tier.
styleguide.fontLinksobjectKeyed by font family name. Each entry has type (google or custom), files (weight → URL), optional category (Google only), optional displayName (custom only). Omitted when no family resolves to Google or @font-face URLs.
styleguide.components.buttonobjectThree variants: primary, secondary, link. Each variant has:
  • backgroundColor
  • color
  • borderColor
  • borderRadius
  • borderWidth
  • borderStyle
  • padding
  • minWidth
  • minHeight
  • fontFamily
  • fontFallbacks
  • fontSize
  • fontWeight
  • textDecoration
  • textDecorationColor
  • boxShadow
  • css: ready-to-paste declaration block
styleguide.components.cardobject
  • backgroundColor
  • textColor
  • borderColor
  • borderRadius
  • borderWidth
  • borderStyle
  • padding
  • boxShadow
  • css: ready-to-paste declaration block

Extract just the fonts

GET /web/fonts takes a domain (or a direct URL) and returns only the typography subset: every font family the site uses, with weights, fallbacks, usage counts, and downloadable file URLs.
curl -G https://api.context.dev/v1/web/fonts \
  -H "Authorization: Bearer $CONTEXT_DEV_API_KEY" \
  --data-urlencode "domain=vercel.com"
5 credits per successful call

Request Parameters

Either domain or directUrl must be provided, but not both.
ParameterTypeDescription
domainstringDomain to extract fonts from (e.g. vercel.com). Normalized automatically.
directUrlstring (URI)A specific URL to fetch fonts from directly, bypassing domain resolution.
maxAgeMsintegerMax cache age before a hard refresh. Defaults to 7776000000 (90 days). Clamped to [86400000, 31536000000] (1 day – 1 year).
timeoutMSinteger (1000–300000)Abort with a 408 if the request exceeds this many milliseconds. Max 300000 (5 min).

Response

{
  "status": "ok",
  "domain": "vercel.com",
  "code": 200,
  "fonts": [
    {
      "font": "Geist",
      "uses": ["body", "div", "header", "nav", "h1", "h2", "h3", "p", "button"],
      "fallbacks": ["Arial", "system-ui", "-apple-system", "Segoe UI", "Roboto", "sans-serif"],
      "num_elements": 534,
      "num_words": 9320,
      "percent_elements": 91,
      "percent_words": 99
    },
    {
      "font": "Geist Mono",
      "uses": ["code", "pre", "kbd"],
      "fallbacks": ["ui-monospace", "SFMono-Regular", "Menlo", "monospace"],
      "num_elements": 55,
      "num_words": 94,
      "percent_elements": 9,
      "percent_words": 1
    }
  ],
  "fontLinks": {
    "Geist": {
      "type": "google",
      "category": "sans-serif",
      "files": {
        "400": "https://fonts.gstatic.com/s/geist/v4/gyBhhwUxId8gMGYQMKR3pzfaWI_RnOM4nZPby1QNtA.ttf",
        "500": "https://fonts.gstatic.com/s/geist/v4/gyBhhwUxId8gMGYQMKR3pzfaWI_RruM4nZPby1QNtA.ttf",
        "600": "https://fonts.gstatic.com/s/geist/v4/gyBhhwUxId8gMGYQMKR3pzfaWI_RQuQ4nZPby1QNtA.ttf",
        "700": "https://fonts.gstatic.com/s/geist/v4/gyBhhwUxId8gMGYQMKR3pzfaWI_Re-Q4nZPby1QNtA.ttf"
      }
    }
  }
}
FieldTypeDescription
statusstring"ok" on success.
domainstringNormalized domain that was processed.
codeintegerHTTP status code.
fonts[]arrayOne entry per font family on the page, ordered by usage.
fonts[].fontstringPrimary face (first family in the computed stack).
fonts[].uses[]arrayCSS selectors or element types where this font is used.
fonts[].fallbacks[]arrayFallback families from the computed stack.
fonts[].num_elementsnumberElement count using this font.
fonts[].num_wordsnumberWord count rendered in this font.
fonts[].percent_elementsnumberShare of all elements using this font.
fonts[].percent_wordsnumberShare of all words rendered in this font.
fontLinksobjectOptional. Same shape as styleguide.fontLinks: keyed by family with type, files, optional category and displayName. Omitted when no family resolves to Google or @font-face URLs.

Handle errors

A non-2xx response returns an { message, error_code, status } envelope. The common ones:
Statuserror_codeMeaningWhat to do
400INPUT_VALIDATION_ERRORMissing both domain and directUrl, or both were suppliedPass exactly one.
401UNAUTHORIZEDAPI key missing, invalid, or deletedRe-check the env var and the dashboard.
408REQUEST_TIMEOUTPage didn’t render before timeoutMS (or 5 min default)Retry once with backoff; the second hit usually succeeds.
500INTERNAL_ERRORTransient server errorRetry once with backoff; if it persists, contact support.
A 400 from omitting both domain and directUrl looks like:
{
  "status": "error",
  "error_code": "INPUT_VALIDATION_ERROR",
  "message": [
    { "code": "custom", "message": "Either directUrl or domain must be provided, but not both", "path": [] }
  ]
}
For the full catalog of error codes, see Troubleshooting.

Use cases

Next steps

Prefetch for Faster Response

Hide cold-hit latency from your users.

Handle Rate Limits

Backoff strategies, client cache, and prefetch fallbacks.

Best Practices

Caching, error handling, and key hygiene.

Troubleshooting

Status codes, retry patterns, and common errors.