Overview
Generates a new API key for the user. The old key is immediately invalidated.
This action cannot be undone! The old API key will stop working immediately.
Authentication
Requires User API Key in the X-API-Key header (the old key you’re replacing).
Request
POST https://api.syncline.run/v1/user/api-key/regenerate
No request body required.
Response
{
"success": true,
"api_key": "sk_user_new_abc123xyz789...",
"message": "API key regenerated successfully"
}
Always true on successful regeneration
Your new API key. Save this immediately - it will never be shown again.
When to Regenerate
Security Breach
If your API key is exposed:
const response = await fetch('https://api.syncline.run/v1/user/api-key/regenerate', {
method: 'POST',
headers: {
'X-API-Key': oldUserApiKey
}
});
const { api_key } = await response.json();
// Save new key immediately
localStorage.setItem('syncline_user_api_key', api_key);
Regular Rotation
Rotate keys periodically as a security best practice:
// Remind users to rotate keys every 90 days
if (daysSinceLastRotation > 90) {
showNotification({
title: 'Security Reminder',
message: 'It's time to rotate your API key',
action: 'Rotate Now',
onClick: async () => {
const { api_key } = await regenerateUserKey();
localStorage.setItem('syncline_user_api_key', api_key);
showSuccess('API key rotated successfully!');
}
});
}
User Flow
Settings Page
// In user settings page
function SecuritySettings() {
const [showConfirm, setShowConfirm] = useState(false);
const handleRegenerate = async () => {
if (!confirm('This will invalidate your old API key. Continue?')) {
return;
}
try {
const { api_key } = await fetch(
'https://api.syncline.run/v1/user/api-key/regenerate',
{
method: 'POST',
headers: { 'X-API-Key': currentApiKey }
}
).then(r => r.json());
// Save new key
localStorage.setItem('syncline_user_api_key', api_key);
// Show success message with new key
alert(`New API Key: ${api_key}\n\nSave this key - it won't be shown again!`);
// Reload page with new key
window.location.reload();
} catch (error) {
alert('Failed to regenerate API key: ' + error.message);
}
};
return (
<div>
<h3>API Key</h3>
<p>Current key: {currentApiKey.substring(0, 20)}...</p>
<button onClick={handleRegenerate}>
Regenerate API Key
</button>
<p className="warning">
⚠️ This will immediately invalidate your old key
</p>
</div>
);
}
Automated Rotation
// Automatically rotate after suspicious activity
async function handleSuspiciousActivity(userId) {
console.warn(`Suspicious activity detected for user ${userId}`);
// Automatically regenerate key
const { api_key } = await regenerateUserKey();
// Email user about security action
await sendEmail({
to: user.email,
subject: 'Security Alert: API Key Regenerated',
body: `
We detected suspicious activity on your account and automatically
regenerated your API key as a security measure.
Your new API key is: ${api_key}
If this wasn't you, please contact support immediately.
`
});
// Log security event
await auditLog.create({
event: 'api_key_auto_regenerated',
user_id: userId,
reason: 'suspicious_activity',
timestamp: new Date()
});
}
Best Practices
Show Key Only Once
function RegenerateKeyButton() {
const [newKey, setNewKey] = useState(null);
const handleClick = async () => {
const { api_key } = await regenerateKey();
setNewKey(api_key);
};
if (newKey) {
return (
<div className="key-display">
<h3>Your New API Key</h3>
<code>{newKey}</code>
<button onClick={() => navigator.clipboard.writeText(newKey)}>
Copy to Clipboard
</button>
<p>⚠️ Save this key now - it won't be shown again!</p>
</div>
);
}
return (
<button onClick={handleClick}>
Regenerate API Key
</button>
);
}
Require Confirmation
async function regenerateWithConfirmation() {
// Show modal
const confirmed = await showModal({
title: 'Regenerate API Key?',
message: 'Your old API key will immediately stop working. Continue?',
confirmText: 'Yes, Regenerate',
cancelText: 'Cancel'
});
if (!confirmed) return;
// Proceed with regeneration
const { api_key } = await regenerateKey();
return api_key;
}
Audit Trail
async function regenerateWithAudit(userId) {
const { api_key } = await regenerateKey();
// Log the rotation
await db.securityEvents.create({
user_id: userId,
event: 'api_key_regenerated',
timestamp: new Date(),
ip_address: req.ip,
user_agent: req.headers['user-agent']
});
return api_key;
}
Security Considerations
The old key stops working immediately:
const oldKey = 'sk_user_old_abc123...';
// Regenerate
const { api_key: newKey } = await regenerateKey();
// Old key is now INVALID
try {
await fetch('https://api.syncline.run/v1/user/info', {
headers: { 'X-API-Key': oldKey }
});
} catch (error) {
console.log('Old key no longer works ✓');
}
Never Share Keys
// Bad: Sharing key with others
const sharedKey = 'sk_user_abc123...';
sendToColleague(sharedKey); // ❌ Never do this!
// Good: Each user has their own key
const myKey = localStorage.getItem('syncline_user_api_key'); // ✓
Error Responses
Invalid API Key
{
"error": "Unauthorized",
"message": "Invalid or missing API key"
}
Rate Limit
{
"error": "Too many regeneration attempts",
"message": "Please wait before regenerating again"
}