Skip to content

Events & Callbacks

The widget communicates with your application through standard DOM Custom Events. All events bubble and are composed (they cross the Shadow DOM boundary), so you can listen on the widget element or any ancestor.

const widget = document.querySelector('ats-widget');
widget.addEventListener('allfeat:complete', (e) => {
console.log(e.detail); // Event payload
});

Events follow the registration flow:

ready → upload-start → upload-progress (×N) → upload-complete
→ confirmed → step (×N) → complete

On error at any stage:

... → failed

Token expiry can occur at any point:

... → token-expired → (setToken) → retry

Emitted when the widget is initialized and ready.

{ mode: 'register' | 'update' | 'access' }

Emitted when the audio file upload begins.

{ filename: string; size: number }

Emitted repeatedly during upload. Useful for displaying an external progress bar.

{ progress: number; loaded: number; total: number }
// progress: 0–100 (percentage)

Emitted when the upload finishes successfully.

{ filename: string }

Emitted when the blockchain transaction has been submitted.

{ transactionId: string }

Emitted on each blockchain tracking step change.

{
step: 'validating' | 'transferring_tokens'
| 'preparing_transaction' | 'signing'
| 'submitting' | 'confirming';
progress: number; // 0–100
description?: string;
}

Emitted when the work is successfully registered on the blockchain.

{
atsId: number | null; // Unique work identifier
txHash: string; // Blockchain transaction hash
blockNumber: number; // Block number
explorerUrl: string; // Blockchain explorer URL
accessCode?: string; // Access code (register mode only)
}

Emitted when a critical error occurs.

{
error: string; // Error message
stage?: string; // Stage where the error occurred
code?: string; // Error code (see Reference > Error Codes)
}

Emitted when the JWT token has expired (401 response).

{ pendingAction: string }

After receiving this event, call widget.setToken(newToken) so the widget automatically retries the pending action. You have 60 seconds before the widget transitions to a failed state.

Emitted for non-fatal errors (the widget can continue operating).

{
stage: string;
error: string;
code?: string;
details?: unknown;
}
const widget = document.querySelector('ats-widget');
widget.addEventListener('allfeat:ready', (e) => {
console.log(`Widget ready in ${e.detail.mode} mode`);
});
widget.addEventListener('allfeat:upload-progress', (e) => {
updateProgressBar(e.detail.progress);
});
widget.addEventListener('allfeat:step', (e) => {
updateStatusMessage(e.detail.description);
});
widget.addEventListener('allfeat:complete', (e) => {
const { atsId, txHash, accessCode } = e.detail;
showSuccess(`ATS #${atsId} — TX: ${txHash}`);
if (accessCode) {
// Save access code for future operations
saveToDatabase({ atsId, accessCode });
}
});
widget.addEventListener('allfeat:failed', (e) => {
showError(e.detail.error);
reportToSentry(e.detail);
});
widget.addEventListener('allfeat:token-expired', async () => {
const { token } = await refreshToken();
widget.setToken(token);
});