The Shield API

A single GET endpoint returns a fresh SVG rendered on the Cloudflare edge — no client-side JavaScript, no third-party CDN, no stale cache.

Every badge is built from four simple query parameters, validated at the edge, and returned as an immutable image/svg+xml response in under 40ms p99.

GET https://newshields.vercel.app/api/badge.svg?label=…&title=…&icon=…&theme=…


Quick start

Drop this one-liner into any README, blog post, or HTML page and you're done:

![My Badge](https://newshields.vercel.app/api/badge.svg?label=Built+with&title=Svelte&icon=svelte&theme=aurora)

Or embed it as an <img> tag in any HTML document:

<img src="https://newshields.vercel.app/api/badge.svg?label=Built+with&title=Svelte&icon=svelte&theme=aurora" alt="Built with Svelte" />
Build visually instead

Endpoint

There is one public endpoint. All parameters are passed as query strings.

GET /api/badge.svg

The endpoint is served from Cloudflare's global edge network. Requests are rate-limited to 60 per minute per IP. Responses are cached with Cache-Control: public, max-age=31536000, immutable.


Parameters

All parameters are optional — sane defaults are applied when omitted.

NameTypeDefaultMax lengthDescription
labelstringPowered by28 charsUpper-line text displayed above the title.
titlestringNew Shields36 charsLower-line bold text — the main badge name.
iconstringsvelteAny SVGL slug. Unknown slugs render a placeholder.
themeenumauroraOne of the 8 preset themes. See Themes.

Validation rules

  • Strings are URL-decoded and trimmed before validation.
  • Parameters exceeding max length return 400 Bad Request.
  • Unknown theme values silently fall back to aurora.
  • Unknown icon slugs render an empty placeholder rectangle.

Themes

Eight hand-tuned presets are available. Each defines a surface gradient, accent border, glow color, and text colors for label and title.

Pass the theme name as the theme query parameter. Full palette definition in src/content/themes.ts.


Response

A successful request returns 200 OK with the following headers:

HTTP/1.1 200 OK
Content-Type: image/svg+xml; charset=utf-8
Cache-Control: public, max-age=31536000, immutable
Vary: Accept-Encoding

The body is a fully self-contained <svg> — embedded gradients, inline icon <path> data, no external font or image requests.


Errors

Error responses are plain text with an appropriate HTTP status code.

StatusWhen
400A parameter exceeds its maximum length or is otherwise invalid.
429Rate limit exceeded — more than 60 requests per minute from the same IP.
500Renderer error. Edge-cached responses may still be served.

GitHub READMEs

GitHub proxies all <img> tags through camo, a server-side image proxy. This means the badge is fetched once by camo and cached — individual visitors don't hit the edge directly.

To bust GitHub's camo cache and force a re-fetch, append a version query string:

![Badge](https://newshields.vercel.app/api/badge.svg?icon=svelte&theme=aurora&v=2)

Increment v whenever you want GitHub to pull a fresh version.


Self-host

New Shields is MIT-licensed. Deploy your own instance to Cloudflare Pages in three commands:

git clone https://github.com/konlyzx/newshields
cd newshields && pnpm install
pnpm deploy

The API lives in src/routes/api/badge.svg/+server.ts and only depends on the Cloudflare Workers runtime — no Node-specific APIs required.

© 2026 · New Shields · MIT License