Authentication
BioUI Web supports two auth modes. Choose the one that fits your architecture:
| Mode | Best For | API Key in Browser? |
|---|---|---|
| Token mode (recommended) | Production apps, third-party integrations, HIPAA-compliant deployments | No — key stays server-side |
| Direct mode | Internal tools, prototyping, server-rendered apps where the key is injected at build time | Yes — visible in HTML |
Token Mode (Recommended)
Your backend mints a short-lived JWT for the current user. The browser only sees a scoped, time-limited token — never your API key.
<bio-provider
sdk-key="sdk_your_key"
xuser-token="eyJ..."
base-url="https://api.anybio.io">
<!-- widgets here -->
</bio-provider>How It Works
- Your user logs in to your app (using your own auth — Supabase, Auth0, Firebase, etc.)
- Your backend calls
POST /api/v1/sdk/tokenwith your Write-scoped API key and the user's external ID - AnyBio returns a short-lived JWT (1-hour expiry, RS256-signed, scoped to that user)
- Your frontend passes the JWT to
<bio-provider>viaxuser-token - All widget API calls use the JWT — no API key in the browser
Backend Token Request
POST https://api.anybio.io/api/v1/sdk/token
Authorization: Bearer org_your_write_key
Content-Type: application/json
{
"external_id": "user-123",
"project_key": "proj_your_key"
}Response:
{
"xuser_token": "eyJhbGciOiJSUzI1NiJ9...",
"xuser_id": "550e8400-e29b-41d4-a716-446655440000",
"expires_in": 3600
}Token Refresh
The provider emits an anybio:token:expiring event 5 minutes before expiry. Listen for it and fetch a new token:
document.addEventListener('anybio:token:expiring', async () => {
const { xuser_token } = await fetchNewToken(currentUser.id)
document.getElementById('bio').setAttribute('xuser-token', xuser_token)
})Platform Guides
- Lovable Integration — Supabase Edge Function + Lovable
sdk-key
A public identifier for your project. Safe to include in browser HTML. It does not grant API access on its own.
xuser-token
A short-lived JWT returned by POST /api/v1/sdk/token. Contains the user's AnyBio UUID, project, and organization — all verified server-side on every request.
Direct Mode
For internal tools or prototyping, you can pass credentials directly. The API key is visible in the HTML source.
<bio-provider
api-key="org_your_key"
project-key="proj_your_key"
xuser-id="user-123">
<!-- widgets here -->
</bio-provider>api-key
Your organization's developer key. Sent as Authorization: Bearer <api-key> on every API request.
You can generate and rotate API keys in the AnyBio dashboard under Settings > API Keys.
project-key
Identifies the project within your organization. Each project has its own questionnaires, scoring rules, and user data.
xuser-id
Your application's external user identifier (e.g., a database primary key, Firebase UID, or Auth0 subject).
When <bio-provider> initializes, it calls POST /api/v1/xusers with the xuser-id value. The server resolves (or creates) the corresponding AnyBio UUID.
Identity Ownership
Your application owns the user's identity in both modes. BioUI Web never shows a login screen or stores credentials on the client. This means:
- You control who has access. Only users that your app authenticates can interact with the widgets.
- You can use any auth provider. Firebase, Auth0, Cognito, Supabase, a custom backend — it does not matter.
- User data is scoped. Each user under a given project maps to exactly one AnyBio user record.
Security Considerations
| Concern | Token Mode | Direct Mode |
|---|---|---|
| API key exposure | Key stays server-side. Only a short-lived JWT reaches the browser. | Key is visible in HTML. Use scoped permissions and rotate regularly. |
| Token lifetime | 1-hour JWT with automatic expiry warning event. | N/A — API key doesn't expire (rotate manually). |
| Cross-user access | Impossible — JWT is scoped to one user. | Depends on API key scope. |
| HTTPS | Always required. CDN and API calls use HTTPS. | Same. |
| CORS | Wildcard origin allowed for JWT-authenticated requests. | Requires registered domain in ALLOWED_ORIGINS. |