Skip to content

Quick Start

Add the script to your HTML page from the Allfeat CDN:

<script src="https://cdn.allfeat.org/ats/v1/ats-widget.iife.js"></script>

The <ats-widget> element is immediately available.

  1. Call the Allfeat API from your server to obtain a JWT session token.

    backend/routes/ats-token.ts
    app.post('/api/ats-token', async (req, res) => {
    const response = await fetch('https://ats.api.allfeat.org/v1/sessions', {
    method: 'POST',
    headers: {
    'Content-Type': 'application/json',
    'Origin': 'https://yoursite.com', // domain where the widget is embedded (validated against your allowlist)
    },
    body: JSON.stringify({
    secret_key: process.env.ALLFEAT_SECRET_KEY,
    action_type: 'register',
    allowed_network: 'testnet',
    }),
    });
    if (!response.ok) {
    const error = await response.json();
    return res.status(response.status).json(error);
    }
    const { token, expires_in } = await response.json();
    res.json({ token });
    });
  2. index.html
    <ats-widget
    id="ats-widget"
    site-key="cpk_your_public_key"
    ats-url="https://ats.api.allfeat.org"
    network="testnet"
    mode="register"
    ></ats-widget>
  3. app.js
    const widget = document.getElementById('ats-widget');
    // Fetch the token from your backend
    const { token } = await fetch('/api/ats-token', {
    method: 'POST',
    credentials: 'include',
    }).then(r => r.json());
    // Pass the token to the widget
    widget.setToken(token);
  4. app.js
    // Registration successful
    widget.addEventListener('allfeat:complete', (e) => {
    const { atsId, txHash, accessCode } = e.detail;
    console.log(`Work protected! ATS #${atsId}`);
    // The access code is shown to the user on the success screen.
    // Optionally save it as a backup on your side.
    await saveToDatabase({ atsId, txHash });
    });
    // Automatic token renewal
    widget.addEventListener('allfeat:token-expired', async () => {
    const { token } = await fetch('/api/ats-token', {
    method: 'POST',
    credentials: 'include',
    }).then(r => r.json());
    widget.setToken(token);
    });
    // Error handling
    widget.addEventListener('allfeat:failed', (e) => {
    console.error('Failed:', e.detail.error);
    });
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Protect a Work</title>
<script src="https://cdn.allfeat.org/ats/v1/ats-widget.iife.js"></script>
</head>
<body>
<div style="max-width: 640px; margin: 2rem auto;">
<ats-widget
id="ats-widget"
site-key="cpk_your_public_key"
ats-url="https://ats.api.allfeat.org"
network="testnet"
mode="register"
></ats-widget>
</div>
<script>
const widget = document.getElementById('ats-widget');
async function getToken() {
const res = await fetch('/api/ats-token', {
method: 'POST',
credentials: 'include',
});
const { token } = await res.json();
return token;
}
// Initialize
getToken().then(token => widget.setToken(token));
// Token expired → refresh
widget.addEventListener('allfeat:token-expired', async () => {
widget.setToken(await getToken());
});
// Success
widget.addEventListener('allfeat:complete', (e) => {
const { atsId, accessCode, txHash } = e.detail;
console.log(`ATS #${atsId} registered — TX: ${txHash}`);
// Access code is displayed to the user — optionally save as backup
});
// Error
widget.addEventListener('allfeat:failed', (e) => {
console.error('Error:', e.detail);
});
</script>
</body>
</html>