Best Practices
Production-ready patterns for building with RegPilot.Security
1. Protect API Keys
// ✅ Good - Environment variables
const apiKey = process.env.REGPILOT_API_KEY;
// ❌ Bad - Hardcoded
const apiKey = 'sk_abc123';
// ❌ Bad - Client-side
// Never expose in browser JavaScript!
2. Use Secure Headers
// ✅ Production-safe (won't be stripped)
headers: {
'X-API-Key': process.env.REGPILOT_API_KEY
}
// ⚠️ May be stripped by proxies
headers: {
'Authorization': `Bearer ${apiKey}`
}
3. Rotate Keys Regularly
# Rotate every 90 days
1. Create new key
2. Update all environments
3. Verify new key works
4. Revoke old key
Performance
1. Choose Right Quality Tier
// Simple FAQ - use cheap
await chat('What are your hours?', 'cheap');
// General use - balanced
await chat('Explain quantum computing', 'balanced');
// Complex tasks - frontier
await chat('Review this legal contract', 'frontier');
2. Leverage Caching
// Cache FAQ responses
const faqs = [
'What are your hours?',
'Where are you located?',
'What is your return policy?'
];
// First time: Cache MISS
// Subsequent: Cache HIT (FREE!)
faqs.forEach(q => chat(q, 'cheap'));
3. Optimize Prompts
// ❌ Too verbose
const prompt = `I would like you to please analyze this text and provide me with a detailed summary of the main points, key takeaways, and any important insights that you can identify from the content...`;
// ✅ Concise
const prompt = `Summarize the main points:`;
4. Manage Context Windows
// Keep under 4000 tokens
function trimHistory(messages: Message[]) {
const maxTokens = 4000;
let total = messages.reduce((sum, m) => sum + m.content.length, 0);
while (total > maxTokens * 4 && messages.length > 2) {
messages.splice(1, 1); // Remove oldest
total = messages.reduce((sum, m) => sum + m.content.length, 0);
}
return messages;
}
Error Handling
1. Implement Retries
async function robustChat(messages: any[], maxRetries = 3) {
let delay = 1000;
for (let i = 0; i < maxRetries; i++) {
try {
const response = await fetch('https://regpilot.dev/api/ai/chat', {
method: 'POST',
headers: {
'X-API-Key': process.env.REGPILOT_API_KEY!,
'Content-Type': 'application/json'
},
body: JSON.stringify({ messages, quality: 'balanced' })
});
if (response.ok) return response;
if (response.status === 429) {
const retryAfter = parseInt(response.headers.get('retry-after') || '60');
await new Promise(r => setTimeout(r, retryAfter * 1000));
continue;
}
if (response.status >= 500 && i < maxRetries - 1) {
await new Promise(r => setTimeout(r, delay));
delay *= 2; // Exponential backoff
continue;
}
throw new Error(`HTTP ${response.status}`);
} catch (error) {
if (i === maxRetries - 1) throw error;
}
}
}
2. Handle Specific Errors
try {
const response = await chat(messages);
// Process response
} catch (error) {
if (error.status === 401) {
// Invalid API key
console.error('API key invalid. Please check credentials.');
} else if (error.status === 429) {
// Rate limited
console.error('Rate limit exceeded. Retry later.');
} else if (error.status >= 500) {
// Server error
console.error('Server error. Contact support.');
}
}
3. Log Errors
async function chatWithLogging(messages: any[]) {
const startTime = Date.now();
try {
const response = await chat(messages);
// Log success
logger.info({
action: 'chat_success',
duration: Date.now() - startTime,
model: response.headers.get('x-regpilot-model')
});
return response;
} catch (error) {
// Log error
logger.error({
action: 'chat_error',
duration: Date.now() - startTime,
error: error.message
});
throw error;
}
}
Cost Optimization
1. Monitor Spending
// Check usage regularly
const stats = await fetch(
`https://regpilot.dev/api/usage?projectId=${projectId}`,
{ headers: { 'X-API-Key': apiKey } }
);
const data = await stats.json();
if (data.budget.remaining < 100) {
console.warn('Low credit balance!');
// Send alert
}
2. Set Budgets
// Enforce budget limits
const MONTHLY_BUDGET = 1000; // $1000
async function checkBudget() {
const usage = await getUsage();
if (usage.budget.used > MONTHLY_BUDGET * 0.9) {
// 90% used - send warning
sendAlert('Budget Warning: 90% used');
}
if (usage.budget.used >= MONTHLY_BUDGET) {
// Budget exceeded - stop requests
throw new Error('Monthly budget exceeded');
}
}
3. Use Quality Tiers Wisely
function selectQuality(taskComplexity: number): string {
if (taskComplexity < 3) return 'cheap';
if (taskComplexity < 7) return 'balanced';
return 'frontier';
}
Compliance
1. Enable Governor for Sensitive Use Cases
// Legal, medical, HR, or high-risk content
const response = await fetch('https://regpilot.dev/api/ai/chat', {
method: 'POST',
headers: {
'X-API-Key': process.env.REGPILOT_API_KEY!,
'Content-Type': 'application/json'
},
body: JSON.stringify({
messages: [...],
governorMetadata: {
actionType: 'legal_advice',
recipientCountry: 'US',
senderId: 'user_123'
}
})
});
2. Monitor Alerts
// Check alerts daily
async function checkAlerts() {
const alerts = await getActiveAlerts();
const critical = alerts.filter(a => a.severity === 'CRITICAL');
if (critical.length > 0) {
// Send immediate notification
sendUrgentAlert(critical);
}
}
3. Maintain Audit Trails
// Store audit IDs for compliance
const auditId = response.headers.get('x-governor-audit-id');
await db.conversations.update({
where: { id: conversationId },
data: {
governorAuditId: auditId,
lastValidated: new Date()
}
});
Development Workflow
1. Separate Environments
# .env.development
REGPILOT_API_KEY=sk_dev_xxx
# .env.staging
REGPILOT_API_KEY=sk_staging_xxx
# .env.production
REGPILOT_API_KEY=sk_prod_xxx
2. Test Before Deploy
// Test script
async function testApi() {
const tests = [
{ name: 'Simple query', quality: 'cheap' },
{ name: 'Complex query', quality: 'frontier' },
{ name: 'With Governor', hasGovernor: true }
];
for (const test of tests) {
try {
await chat([{ role: 'user', content: test.name }]);
console.log(`✅ ${test.name} passed`);
} catch (error) {
console.error(`❌ ${test.name} failed:`, error);
}
}
}
3. Monitor in Production
// Production monitoring
setInterval(async () => {
const health = await checkHealth();
if (!health.ok) {
sendAlert('API health check failed');
}
}, 60000); // Every minute
Deployment
1. CI/CD Integration
# .github/workflows/deploy.yml
- name: Test RegPilot Integration
env:
REGPILOT_API_KEY: ${{ secrets.REGPILOT_API_KEY }}
run: npm test
2. Environment Variables
# Vercel
vercel env add REGPILOT_API_KEY
# Netlify
netlify env:set REGPILOT_API_KEY sk_xxx
# Railway
railway variables set REGPILOT_API_KEY=sk_xxx
3. Health Checks
// Add health check endpoint
app.get('/health', async (req, res) => {
try {
await testRegPilotConnection();
res.json({ status: 'healthy' });
} catch (error) {
res.status(500).json({ status: 'unhealthy', error: error.message });
}
});
Monitoring
1. Track Key Metrics
const metrics = {
requests: 0,
errors: 0,
cacheHits: 0,
totalCost: 0,
avgLatency: 0
};
// Update after each request
function recordMetrics(response: Response) {
metrics.requests++;
metrics.totalCost += parseFloat(response.headers.get('x-credits-charged') || '0');
if (response.headers.get('x-cache-status') === 'HIT') {
metrics.cacheHits++;
}
}
2. Set Up Alerts
// Alert on anomalies
if (metrics.errors / metrics.requests > 0.05) {
// Error rate > 5%
sendAlert('High error rate detected');
}
if (metrics.cacheHits / metrics.requests < 0.1) {
// Cache hit rate < 10%
sendAlert('Low cache hit rate');
}
3. Dashboard Integration
// Send to monitoring service
await prometheus.gauge('regpilot_requests_total', metrics.requests);
await prometheus.gauge('regpilot_cost_usd', metrics.totalCost);
await prometheus.gauge('regpilot_cache_hit_rate',
metrics.cacheHits / metrics.requests
);
Related: Error Handling | Troubleshooting