Badge & Widget
Show visitors that your file is cryptographically signed. Drop a snippet on any page; the widget fetches verification data and renders a card, badge, or minimal indicator.
No build step. No framework requirements. No dependencies. ~3 KB minified.
Quick Start
<div data-flowsta-hash="abc123..."></div>
<script src="https://flowsta.com/sign-it/widget.js" async></script>Replace abc123... with the SHA-256 hash of your file. On page load, the script finds every [data-flowsta-hash] element and renders verification UI into it.
Attributes
| Attribute | Values | Default | Notes |
|---|---|---|---|
data-flowsta-hash | 64-char hex SHA-256 | — | Required. |
data-flowsta-style | card, badge, minimal | card | See examples below. |
data-flowsta-theme | light, dark | light | Auto-detects prefers-color-scheme if unset. |
data-flowsta-api | API base URL | https://auth-api.flowsta.com | Override for self-hosted or staging. |
Styles
Card (default)
Full card with signer name/avatar, timestamp, content-rights badges, and a "Verify on Flowsta" link.
<div data-flowsta-hash="abc123..." data-flowsta-style="card"></div>Best for landing pages, portfolio items, release notes.
Badge
Compact inline pill: "✓ Signed · by Alice" with a hover tooltip of content rights.
<div data-flowsta-hash="abc123..." data-flowsta-style="badge"></div>Best for blog posts, file download pages, image captions.
Minimal
Just a small coloured dot + "Signed" / "Unsigned" status. For density-constrained UI.
<div data-flowsta-hash="abc123..." data-flowsta-style="minimal"></div>Theming
All three styles respect data-flowsta-theme="light|dark". Omit the attribute to follow the user's system theme via prefers-color-scheme.
Styling lives in shadow DOM, so your site's CSS cannot affect it, and the widget's CSS cannot affect your site.
Content Security Policy
If your site has a strict CSP, allow:
script-src https://flowsta.com
connect-src https://auth-api.flowsta.comMultiple Badges
The widget handles an unlimited number of hashes on the same page. Each [data-flowsta-hash] element is rendered independently.
<!-- Each image gets its own badge -->
<figure>
<img src="photo1.jpg" />
<div data-flowsta-hash="<sha256 of photo1.jpg>" data-flowsta-style="badge"></div>
</figure>
<figure>
<img src="photo2.jpg" />
<div data-flowsta-hash="<sha256 of photo2.jpg>" data-flowsta-style="badge"></div>
</figure>Custom Rendering — Badge API
For full control over layout, skip the widget and call the badge endpoint directly.
SVG
GET https://auth-api.flowsta.com/api/v1/sign-it/badge?hash=<sha256>&format=svgReturns an SVG image you can embed directly:
<img src="https://auth-api.flowsta.com/api/v1/sign-it/badge?hash=abc123..." alt="Signed with Flowsta" />JSON
GET https://auth-api.flowsta.com/api/v1/sign-it/badge?hash=<sha256>&format=jsonResponse:
{
"file_hash": "abc123...",
"signed": true,
"signer_count": 1,
"signers": [
{
"display_name": "Alice",
"username": "alice",
"timestamp": 1712345678,
"verify_url": "https://flowsta.com/sign-it/?hash=abc123..."
}
],
"content_rights": {
"license": "CC BY-NC 4.0",
"ai_training": "NotAllowed",
"commercial_licensing": "OpenToLicensing",
"contact_preference": "AllowContactRequests"
},
"verify_url": "https://flowsta.com/sign-it/?hash=abc123..."
}Render it however you like — React, server-side, static site generator, anything.
Cache
Both SVG and JSON responses include Cache-Control: public, max-age=300 (5 minutes). Safe for CDN edge caching.
Getting Your File's Hash
Use any SHA-256 tool, or via the SDK:
import { hashFile } from '@flowsta/auth';
const hash = await hashFile(file); // "abc123..."Or in the terminal:
# macOS / Linux
shasum -a 256 yourfile.jpg
# Windows
certutil -hashfile yourfile.jpg SHA256Examples
WordPress / Blog Post
Paste this inside any post:
<div data-flowsta-hash="abc123..." data-flowsta-style="card"></div>
<script src="https://flowsta.com/sign-it/widget.js" async></script>The <script> only needs to load once per page — add it to your theme if you use multiple badges.
React
import { useEffect } from 'react';
export function FlowstaBadge({ hash, style = 'card' }: { hash: string; style?: string }) {
useEffect(() => {
if (!document.querySelector('script[src*="flowsta.com/sign-it/widget.js"]')) {
const s = document.createElement('script');
s.src = 'https://flowsta.com/sign-it/widget.js';
s.async = true;
document.head.appendChild(s);
}
}, []);
return <div data-flowsta-hash={hash} data-flowsta-style={style} />;
}Static Site (Hugo, 11ty, Astro, etc.)
Use the SVG endpoint so there's no JavaScript:
<a href="https://flowsta.com/sign-it/?hash={{ .Hash }}">
<img src="https://auth-api.flowsta.com/api/v1/sign-it/badge?hash={{ .Hash }}" alt="Signed with Flowsta" />
</a>See Also
- Verification API — full signature details, not just badge data
- Content Rights — machine-readable rights for each signed file
- Developer Guide — sign files from your own app