Widget

The widget is a three-step Web Component for hostname entry, DNS instructions and live HTTPS status. Your API key remains on your server; the browser receives a short-lived token bound to its origin and the domains it creates.

The preview uses local demo data and makes no API request.

1. Create a session on your server

POST /widget-sessions · scope widget:write · idempotent · response 201

Server examples
curl -X POST https://api.subdomain.to/v1/widget-sessions \
  -H "Authorization: Bearer $SUBDOMAINTO_API_KEY" \
  -H "Idempotency-Key: widget-customer-42" \
  -H "Content-Type: application/json" \
  -d '{"external_customer_id":"customer-42","allowed_origins":["https://app.example.com"]}'

The response contains token, expires_at, and expires_in: 1800. Send only token to the browser. Allowed origins must be HTTPS origins without a path, query or fragment; HTTP is accepted only for localhost development.

2. Embed the component

HTML
<script type="module" src="https://cdn.subdomain.to/widget/v1/subdomain-widget.js"></script>

<subdomain-to-widget
  token="WIDGET_SESSION_TOKEN"
  api-base="https://api.subdomain.to"
  lang="en">
</subdomain-to-widget>
Attribute Default Purpose
token required Short-lived token returned by /widget-sessions.
api-base https://api.subdomain.to API origin, mainly overridden in local development.
lang en UI language: en or fr.
demo absent Uses deterministic local data and never calls the API.

3. Listen for lifecycle events

JAVASCRIPT
const widget = document.querySelector('subdomain-to-widget');

widget.addEventListener('subdomain-to:created', ({detail}) => {
  console.log('Created domain', detail.id);
});

widget.addEventListener('subdomain-to:status', ({detail}) => {
  console.log('Current status', detail.status);
});

widget.addEventListener('subdomain-to:error', ({detail}) => {
  console.error(detail.code, detail.message);
});

subdomain-to:created is emitted after creation. subdomain-to:status is emitted after creation and whenever the lifecycle status changes. subdomain-to:error contains a stable code and safe message.

Browser endpoints and polling

The component calls these endpoints with the widget token as a Bearer token:

Endpoint Purpose
POST /widget/domains Create the domain and return dns_records.
GET /widget/domains/{id} Read the domain status every 10 seconds.
POST /widget/domains/{id}/verify Request an immediate DNS verification.

The API enforces the browser Origin, organization and widget session. A session cannot read or verify a domain created by another session. Polling stops when the domain becomes active or terminal, the token expires, or the component is removed.

Theme

CSS
subdomain-to-widget {
  --sdt-primary: #635bff;
  --sdt-background: #ffffff;
  --sdt-color: #111827;
  --sdt-border-radius: 14px;
}

The component uses Shadow DOM, so these custom properties are the supported styling interface.

Errors

Common error codes include missing_token, widget_token_expired, invalid_widget_token, origin_forbidden, destination_not_found, domain_conflict, widget_domain_not_found, and widget_request_failed. When a token expires, create a new session on your server and replace the component's token attribute.