Authentication
Implement user authentication with magic links and guest access
Arky uses passwordless authentication via magic links (email verification codes). Users enter their email, receive a 6-digit code, and verify it to log in. No passwords needed.
How It Works
- User enters their email
- A 6-digit verification code is sent to their inbox
- User enters the code
- Tokens are issued and stored automatically
If the email doesn’t match an existing account, one is created automatically on verification.
Magic Link Authentication
Step 1: Request a Code
/v1/auth/code sdk.auth.code(params) await sdk.auth.code({
email: 'user@example.com',
});
// User receives email with 6-digit verification code
Step 2: Verify the Code
/v1/auth/verify sdk.auth.verify(params) const result = await sdk.auth.verify({
email: 'user@example.com',
code: '123456',
});
// Tokens are automatically stored via the setToken callback
console.log('Logged in:', result.accessToken);
That’s it. No registration step, no password, no email confirmation flow. The verify step handles everything: creates the account if needed, issues tokens, and stores them.
Business-Scoped Authentication
For multi-tenant apps where users belong to a specific business, use business-scoped auth. The verification email is branded to the business.
// Step 1: Request code (scoped to business)
await sdk.auth.businessCode('biz_abc123', {
email: 'customer@example.com',
});
// Step 2: Verify code
const result = await sdk.auth.businessVerify('biz_abc123', {
email: 'customer@example.com',
code: '123456',
});
Guest Access
Allow users to browse and interact without logging in:
// Create a guest session (idempotent - safe to call multiple times)
await sdk.auth.signInAnonymously();
// Check if current user is a guest
const isGuest = await sdk.auth.isGuest();
if (isGuest) {
// Show login prompt
}
Guest accounts are automatically converted to full accounts when the user verifies their email. Any data associated with the guest session (cart, subscriptions) is preserved.
Token Management
Tokens are managed via the getToken and setToken callbacks you provide during SDK initialization:
import { createSdk } from '@arky/sdk';
const sdk = createSdk({
businessId: 'biz_abc123',
getToken: async () => {
const stored = localStorage.getItem('arky_tokens');
return stored ? JSON.parse(stored) : null;
},
setToken: async (tokens) => {
if (tokens) {
localStorage.setItem('arky_tokens', JSON.stringify(tokens));
} else {
localStorage.removeItem('arky_tokens');
}
},
});
Refreshing Tokens
Access tokens expire after 1 hour. Use the refresh token (valid for 7 days) to get a new one:
const result = await sdk.auth.refresh({
refreshToken: 'eyJhbGciOiJIUzI1NiIs...',
});
Logging Out
Clear the stored tokens:
function logout() {
localStorage.removeItem('arky_tokens');
}
Complete Auth Flow Example
import { createSdk } from '@arky/sdk';
const sdk = createSdk({
businessId: 'biz_abc123',
getToken: async () => {
const stored = localStorage.getItem('arky_tokens');
return stored ? JSON.parse(stored) : null;
},
setToken: async (tokens) => {
if (tokens) {
localStorage.setItem('arky_tokens', JSON.stringify(tokens));
} else {
localStorage.removeItem('arky_tokens');
}
},
});
// Check auth state
async function checkAuth() {
const isGuest = await sdk.auth.isGuest();
if (isGuest) return null;
return await sdk.account.getMe({});
}
// Login flow
async function login(email: string) {
await sdk.auth.code({ email });
// Show code input UI...
}
async function verifyLogin(email: string, code: string) {
await sdk.auth.verify({ email, code });
// Tokens stored automatically, user is logged in
return await sdk.account.getMe({});
}
// Logout
function logout() {
localStorage.removeItem('arky_tokens');
}
Error Handling
try {
await sdk.auth.verify({
email: 'user@example.com',
code: '000000',
});
} catch (error) {
// Invalid or expired code
console.error('Verification failed:', error.message);
}
Next Steps
- Core Concepts - Learn about businesses, resources, and permissions
- Authentication API Reference - Complete auth & account API documentation
- Error Handling - Handle errors gracefully