Docs API
SVG Endpoints
Server-rendered badges and cards for GitHub READMEs and anywhere else that only accepts a static image.
All SVG endpoints are server-side rendered Astro API routes exposed at buxx.me. They’re designed to be embedded in GitHub READMEs and other Markdown files that only support static images.
Use <picture> + <source media="(prefers-color-scheme: ...)"> to switch themes automatically based on the viewer’s OS preference (supported by GitHub).
GET /api/activity-panel.svg
A stats panel displaying recent GitHub coding activity. Intended to sit alongside the GitHub Stats card.
All values are passed as query parameters — the server renders them verbatim into the SVG. Actual data collection is handled separately by the sync-recent-activity GitHub Actions script.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
theme |
string | dark |
Color scheme: dark or light |
days |
string | 7 |
Length of the activity window (display only) |
projects |
string | 0 |
Number of active projects |
commits |
string | 0 |
Total commits in the window |
added |
string | 0 |
Lines added (e.g. +38,501) |
removed |
string | 0 |
Lines removed (e.g. -12,388) |
net |
string | 0 |
Net line delta (e.g. +26,113) |
lph |
string | 0 |
Average lines per hour (e.g. +155) |
exp |
string | — | Unix expiry timestamp for signed access when auth is enabled |
sig |
string | — | HMAC signature for signed access when auth is enabled |
Rows rendered
activity scan—last {days} daysactive projects—{projects}total commits—{commits}code delta—{added}/{removed}/ net{net}(green/red/neutral colored)avg output—{lph} lines/hr
Dimensions: 330 × 142px (height is computed: paddingY×2 + rows×22)
Cache: public, max-age=300, s-maxage=300 (5 minutes)
Animation: Each row fades in with a staggered 80ms delay
Auth: When ACTIVITY_PANEL_SIGNING_SECRET is configured, requests must include valid exp and sig values.
Example (GitHub README)
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://buxx.me/api/activity-panel.svg?theme=dark&days=7&projects=11&commits=167&added=%2B38%2C501&removed=-12%2C388&net=%2B26%2C113&lph=%2B155">
<source media="(prefers-color-scheme: light)" srcset="https://buxx.me/api/activity-panel.svg?theme=light&days=7&projects=11&commits=167&added=%2B38%2C501&removed=-12%2C388&net=%2B26%2C113&lph=%2B155">
<img height="155" src="https://buxx.me/api/activity-panel.svg?theme=dark&days=7&projects=11&commits=167&added=%2B38%2C501&removed=-12%2C388&net=%2B26%2C113&lph=%2B155" alt="Recent Activity Stats" />
</picture>
GET /api/status.svg
An animated badge showing a rotating status word with a pulsing green dot.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
theme |
string | dark |
Color scheme: dark or light |
Dimensions: 200 × 40px
Cache: public, max-age=10, s-maxage=10 (10 seconds)
Animation: Pulsing dot; status word rotates every 10 seconds based on server time (25 words in pool)
Example
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://buxx.me/api/status.svg?theme=dark">
<source media="(prefers-color-scheme: light)" srcset="https://buxx.me/api/status.svg?theme=light">
<img src="https://buxx.me/api/status.svg?theme=dark" alt="Status" />
</picture>
GET /api/site-badge.svg
A compact badge linking to buxx.me, with an arrow icon.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
theme |
string | dark |
Color scheme: dark, light, glass, or neon |
style |
string | default |
Visual style: default, gradient, glass, neon |
Dimensions: 130 × 32px
Cache: public, max-age=86400 (24 hours)
Example
<a href="https://buxx.me">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://buxx.me/api/site-badge.svg?theme=dark">
<source media="(prefers-color-scheme: light)" srcset="https://buxx.me/api/site-badge.svg?theme=light">
<img src="https://buxx.me/api/site-badge.svg?theme=dark" alt="Visit buxx.me" height="32" />
</picture>
</a>
GET /api/project.svg
A project card with live GitHub star count, description, role badge, and technology tags. Fetches data from the GitHub GraphQL API at request time.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
project |
string | — | Project key (required, see below) |
theme |
string | dark |
Color scheme: dark or light |
Available project keys
| Key | Repository |
|---|---|
tutubetterrules |
bunizao/TutuBetterRules |
attegi |
bunizao/Attegi |
mirrored |
bunizao/mirrored |
ogis |
bunizao/ogis |
always-attend |
bunizao/always-attend |
Dimensions: 400 × 160px
Cache: public, max-age=3600 (1 hour)
Note: Requires GITHUB_TOKEN env var with repository read access for live star counts.
Example
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://buxx.me/api/project.svg?project=tutubetterrules&theme=dark">
<source media="(prefers-color-scheme: light)" srcset="https://buxx.me/api/project.svg?project=tutubetterrules&theme=light">
<img src="https://buxx.me/api/project.svg?project=tutubetterrules&theme=dark" alt="TutuBetterRules" />
</picture>
GET /api/tech-stack.svg
An infinite-scrolling horizontal marquee of technology tags.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
theme |
string | dark |
Color scheme: dark or light |
Dimensions: 800 × 60px
Cache: public, max-age=3600 (1 hour)
Animation: Continuous left scroll; the tag list is duplicated to ensure seamless looping
Example
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://buxx.me/api/tech-stack.svg?theme=dark">
<source media="(prefers-color-scheme: light)" srcset="https://buxx.me/api/tech-stack.svg?theme=light">
<img src="https://buxx.me/api/tech-stack.svg?theme=dark" alt="Tech Stack" />
</picture>
GET /logo/{id}.svg
The site’s pixel-art marks, used as favicons and wherever the logo appears as
an image. Prerendered static files, not SSR like the badges above — which is
why they are the one SVG family served from buxx.me directly rather than
through /api.
id |
Mark | Served by |
|---|---|---|
tutu |
Blue accent (oklch(0.7 0.12 240)), 12 × 14 grid |
both Workers |
peek |
Red accent (oklch(0.62 0.13 25)), 12 × 9 grid |
both Workers |
tutu-dev, peek-dev |
Same marks on a fixed amber tile (#f59e0b) |
site only |
Cache: public, max-age=31536000, immutable — they are content-stable and
cached for a year.
The -dev variants exist so a local dev tab is visually distinguishable from
production at favicon size. They are only built by the site Worker;
api.buxx.me/logo/tutu-dev.svg does not exist.
Two details matter if you embed these anywhere other than a favicon:
- No
widthorheightattributes. Only aviewBox, so the mark scales to whatever box you put it in and will happily render enormous inside a container with no constraint. Set a size on the<img>. - The non-
devmarks are theme-reactive. The foreground is avar(--favicon-fg)driven by aprefers-color-schememedia query inside the SVG, flipping between#0a0a0aand#fafafa. That means they invert with the viewer’s OS theme with no<picture>element needed — but also that they will disappear against a background matching the viewer’s theme. The-devvariants are fixed-color and do not do this.
Any other id is a 404 from the static asset layer, not from a handler.
Errors and validation
None of the badge endpoints validate their query parameters in the way you
might expect. Bad input almost never produces a 4xx:
| Endpoint | Bad input behavior |
|---|---|
activity-panel.svg |
Every value is rendered verbatim. No numeric parsing, no clamping. |
status.svg, tech-stack.svg, project.svg |
theme is light only on an exact match; every other value, including a typo like Light, silently means dark. |
site-badge.svg |
Unknown theme falls back to dark; unknown style behaves as default. |
project.svg |
Unknown project is the one real error: 404 with a plain-text Project not found body. |
activity-panel.svg returns 401 Unauthorized (plain text,
Cache-Control: private, no-store) when ACTIVITY_PANEL_SIGNING_SECRET is set
and sig/exp do not verify. When that secret is not set the signature
check is skipped entirely and the endpoint is open — which is the deployed
state unless the secret has been configured.
Every SVG response carries a locked-down header set:
Content-Type: image/svg+xml; charset=utf-8
X-Content-Type-Options: nosniff
Referrer-Policy: no-referrer
Content-Security-Policy: default-src 'none'; style-src 'unsafe-inline'; font-src 'self';
No Access-Control-Allow-Origin, no ETag, no Vary. The CSP is what makes
it safe to serve caller-influenced text inside an SVG document: no script, no
external fetches, inline styles only.
project.svg fetches its star count from GitHub on every cache miss and
swallows every failure — an outage, a rate limit, or a missing token all
produce a card with the star count simply absent, never an error response.
Theme Colors
Dark
| Role | Color |
|---|---|
| Background | #0d1117 |
| Border | #30363d |
| Text | #fafafa |
| Label/muted | #525252 |
| Green | #3fb950 |
| Red | #f85149 |
Light
| Role | Color |
|---|---|
| Background | #ffffff |
| Border | #e5e5e5 |
| Text | #171717 |
| Label/muted | #a3a3a3 |
| Green | #16a34a |
| Red | #dc2626 |
Note:
tech-stack.svgandsite-badge.svguse slightly different palettes internally (#0a0a0abg,#262626border).
Common Notes
- All endpoints are SSR — no prerendering, no static files.
- SVGs use the shared
FONT_CODEserver stack fromsrc/lib/fonts.ts, the server-side mirror of the CSS--font-codetoken. - GitHub proxies embedded images through Camo, which respects
Cache-Controlheaders. A 5-minute TTL means updates propagate within ~5 minutes. - SVG animations (
@keyframes) work in GitHub’s Markdown renderer as of 2024, but may not display in some third-party Markdown viewers. - The
activity-panel.svgendpoint does not fetch live data — all values come from query parameters. The GitHub Actions workflow inbunizao/bunizaois responsible for computing and injecting the correct values on a schedule.