A single URL that renders live progress bars as SVG, ASCII art, plain text, or an interactive web component. Drop it into any GitHub README, Notion page, or website.
Grab a progress bar in seconds. Try it with curl, embed it in a README, or use the web component for interactive features.
curl "https://api.gru0.dev/progress/v1/day?format=ascii&style=blocks&decimals=1"
# → [███████████████████████████░░░░░░░░░░] 59.7%<script src="https://api.gru0.dev/progress-bar.js" defer></script>
<progress-bar year></progress-bar>Try the interactive playground to build your exact embed.
All API endpoints. The base URL is https://api.gru0.dev.
/progress/v1/progress/v1/day/progress/v1/year/progress/v1/multi/progress/v1/store/progress/v1/store/{id}/progress/v1/store/{id}/progress/v1/store/{id}/progress-bar.jsQuery parameters accepted by the progress endpoints. Values can also be set as attributes on the <progress-bar> element.
formatOutput format: text, ascii, json, svg, element, iframestyleASCII art style: blocks, shades, dots, arrows, line, mosaicwidthBar width in characters for ASCII output (10,200)showSuffix display mode for ASCII: pct, value, both, nonedecimalsDecimal places for the percentage (0,6)colorBar accent color, any valid CSS colorbgCard background color, any valid CSS colordarkDark mode: true/1 or false/0 (SVG and iframe)compactMinimal layout, removes padding and extra spacingno-cardRemoves the card background and shadowvalueCurrent value for custom metrics (non-negative number)maxMaximum value for custom metrics (positive number)unitShort label for the value (max 32 characters)labelCustom label text (max 64 characters)tzIANA timezone, auto-detected via proxy headers, falls back to UTCsrcCustom JSON endpoint URL for the web component to pollrefreshPolling interval in seconds (1,300, default 60)barsPipe-separated bar definitions for multi: Label:value:max[:color]They are really high. You will not hit them.
The element format uses the <progress-bar> custom element. It loads JSON from the API and renders inside a closed Shadow DOM, no site CSS can leak in.
<script src="https://api.gru0.dev/progress-bar.js" defer></script>
<progress-bar value="847" max="1000" label="Sprints" unit="tasks"></progress-bar>Attributes: value, max, label, unit, tz, day, year, color, bg, compact, no-card, src, refresh.
Time-based progress modes (day, year, date-range) tick up every second using client-side interpolation. The server returns start and end epoch milliseconds, and the component calculates the intermediate values locally. Periodic server re-sync keeps it accurate.
The component pauses updates when off-screen using IntersectionObserver, no wasted cycles.
Adapts to any site theme. Reads CSS custom properties from the parent document:--primary, --accent, --card, --surface, --foreground, --radius, --font-mono, and more. Use the color and bg attributes to override.
Create a managed progress bar that you update via API. Useful for dashboards, status pages, and metrics that change over time.
curl -X POST "https://api.gru0.dev/progress/v1/store" \
-H "Content-Type: application/json" \
-d '{"label":"Sprints","value":47,"max":100,"unit":"tasks"}'
# → { "id":"abc123", "writeKey":"wr_...", "badgeUrl":"https://..." }The writeKey is returned only once, store it securely. It is SHA-256 hashed before storage; the raw key is never persisted.
curl -X PATCH "https://api.gru0.dev/progress/v1/store/abc123" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer wr_..." \
-d '{"value":89}'The render endpoint is public. URL query params override stored values for format, style, width, show, color, and more.