Skip to content

Attributes & Methods

Set these directly on the <ats-widget> element.

AttributeTypeRequiredDefaultDescription
site-keystringYesYour organization’s public key (cpk_...)
ats-urlstringYesBase URL of the ATS API (https://ats.api.allfeat.org)
network"testnet" | "mainnet"No"testnet"Blockchain network to use
mode"register" | "update" | "access"No"register"Operation mode
tokenstringNoJWT token (prefer setToken() instead — see Authentication)
<ats-widget
site-key="cpk_your_public_key"
ats-url="https://ats.api.allfeat.org"
network="testnet"
mode="register"
></ats-widget>

Read-only accessors that reflect the current attribute values.

PropertyTypeDescription
siteKeystringCurrent site-key value
atsUrlstringCurrent ats-url value
tokenstringCurrent token value
network'testnet' | 'mainnet'Current network
mode'register' | 'update' | 'access'Current operation mode
maxFileSizenumberMaximum file size in bytes (fetched from API at startup)

Set the JWT authentication token. This is the recommended way to pass the token, as opposed to the HTML attribute. See Authentication for details.

const widget = document.querySelector('ats-widget');
widget.setToken('eyJhbGciOi...');

When called after an allfeat:token-expired event, the widget automatically retries the failed request.

Reset the widget to its initial state. Clears the form, any error state, and returns to the first step.

widget.reset();

Returns the widget’s current internal state. Useful for debugging and analytics.

const state = widget.getState();
// {
// screen: 'FORM' | 'UPLOAD' | 'CONFIRMING' | 'TRACKING' | 'COMPLETE' | 'FAILED',
// jobId?: string,
// transactionId?: string,
// atsId?: number | null,
// accessCode?: string,
// }

The widget reacts to changes on these attributes: site-key, token, ats-url, network, mode.

You can update attributes dynamically:

// Switch to mainnet
widget.setAttribute('network', 'mainnet');
// Switch to update mode — the widget auto-resets when mode changes
widget.setAttribute('mode', 'update');
ConstantValueDescription
Max creators20Maximum number of creators per work
Max title length200 charactersMaximum length of the work title
Default max file size50 MBDefault maximum audio file size (overridden by API response)
Upload retries3Upload retry attempts with exponential backoff (1s, 2s, 4s)
Polling interval3 secondsTransaction status polling interval
Polling timeout120 secondsMaximum time waiting for blockchain confirmation
Token refresh timeout60 secondsTime the widget waits for a new token before failing
Access code formatatc_ + 64 hex chars68-character capability token for work access
Access code poll10 attempts / 2sPolling for access code after registration

The widget validates form data using Zod schemas. Here are the validation rules:

FieldRuleDetails
fullNameRequiredTrimmed, max 255 characters
emailRequiredMust be a valid email, max 255 characters
rolesRequiredAt least 1 role must be selected
ipiOptionalMust match /^[0-9]{1,11}$/ (1–11 digits)
isniOptionalMust match /^[0-9]{15}[0-9X]$/ (15 digits + digit or X, whitespace stripped)

4 roles are available: Author, Composer, Arranger, Adapter.

The form wizard progresses through these sub-steps depending on the mode:

Register mode:

Sub-stepDescription
fileAudio file selection (required)
titleWork title input
creatorsCreator details (name, email, roles, IPI/ISNI)
reviewSummary before submission

Update mode:

Sub-stepDescription
access_codeAccess code entry + API verification
fileAudio file selection (optional — can skip to reuse existing)
titleWork title (pre-filled from existing work)
creatorsCreator details (pre-filled from existing work)
reviewSummary before submission

Access mode:

Sub-stepDescription
access_codeAccess code entry — triggers work lookup

When using the ESM or CJS bundle, you get full type definitions:

import { AllfeatRegister, EVENT_NAMES } from 'allfeat-ats-component';
const widget = document.querySelector('ats-widget') as AllfeatRegister;
widget.addEventListener(EVENT_NAMES.COMPLETE, ((e: CustomEvent) => {
const { atsId, txHash, accessCode } = e.detail;
}) as EventListener);
import type {
AllfeatRegister, // The custom element class
CreatorFormData, // Creator data shape
FormState, // Full form data shape
FormSubStep, // 'file' | 'title' | 'creators' | 'review' | 'access_code'
ComponentState, // Full component state machine
CompletionData, // Post-registration data
AccessData, // Access mode response data
// Event detail types
ReadyDetail,
UploadStartDetail,
UploadProgressDetail,
UploadCompleteDetail,
ConfirmedDetail,
StepDetail,
CompleteDetail,
FailedDetail,
TokenExpiredDetail,
ErrorDetail,
// API types
CreatorRequest,
InitWorkResponse,
PrepareWorkResponse,
ConfirmWorkResponse,
AccessWorkResponse,
TrackingStep,
} from 'allfeat-ats-component';
import {
EVENT_NAMES, // Event name constants
CREATOR_ROLES, // ['Author', 'Composer', 'Arranger', 'Adapter']
TRACKING_PROGRESS, // Step-to-progress mapping
ApiErrorCode, // Error code enum
AtsApiException, // Structured error class
getTrackingSteps, // Returns tracking steps for a given mode
creatorSchema, // Zod creator validator
workFormSchema, // Zod form validator
createEmptyCreator, // Factory for blank creator
createDefaultFormState, // Factory for default form state
} from 'allfeat-ats-component';