Skip to main content

Production Guide

Best practices for deploying Skippy in production.

Environments

EnvironmentBase URLUse For
Testhttps://testapi.skippy.idDevelopment, testing
Productionhttps://api.skippy.idLive applications
warning

Test credentials are not verifiable in production. Use production API for real credentials.

API Key Security

Do

// ✓ Use environment variables
const apiKey = process.env.SKIPPY_API_KEY;

// ✓ Rotate keys periodically
// ✓ Use separate keys per environment
// ✓ Limit key scope to required operations

Don't

// ✗ Never hardcode keys
const apiKey = "sk_live_abc123"; // WRONG

// ✗ Never commit to version control
// ✗ Never expose in client-side code
// ✗ Never share keys between environments

Key Rotation

  1. Create new API key in dashboard
  2. Update your application with new key
  3. Verify new key works
  4. Delete old key

Error Handling

Always handle API errors gracefully:

async function issueCredential(data) {
try {
const response = await fetch('https://api.skippy.id/v1/openidvc/offer', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.SKIPPY_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
});

if (!response.ok) {
const error = await response.json();

if (response.status === 429) {
// Rate limited - implement backoff
await sleep(error.retryAfter * 1000);
return issueCredential(data);
}

throw new Error(error.errors[0].detail);
}

return response.json();
} catch (err) {
console.error('Credential issuance failed:', err);
// Alert your monitoring system
throw err;
}
}

Rate Limiting

EndpointLimit
Credential issuance100/min
Verification requests200/min
Template operations50/min

Handle rate limits:

function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}

async function withRetry(fn, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await fn();
} catch (err) {
if (err.status === 429 && i < maxRetries - 1) {
await sleep(Math.pow(2, i) * 1000); // Exponential backoff
continue;
}
throw err;
}
}
}

Webhook Security

Always verify webhook signatures. See Webhook Verification for implementation.

// Verify before processing
if (!verifyWebhookSignature(req)) {
return res.status(401).send('Invalid signature');
}

Monitoring

Key Metrics to Track

MetricAlert Threshold
API error rate> 5%
Issuance success rate< 95%
Verification latency> 3s
Webhook delivery failures> 3 consecutive

Logging Best Practices

// Log credential operations (without sensitive data)
console.log({
event: 'credential.issued',
offerId: offer.id,
templateId: template.id,
timestamp: new Date().toISOString()
// Don't log: recipientEmail, credentialData
});

Compliance Checklist

Before going live:

  • API keys stored securely (not in code)
  • HTTPS enforced for all webhook endpoints
  • Webhook signatures verified
  • Error handling implemented with retries
  • Rate limiting handled gracefully
  • Logging in place (no PII in logs)
  • Monitoring configured with alerts
  • Data retention policy defined
  • Backup strategy for credential records

Data Retention

Data TypeRecommended Retention
Credential offers90 days after completion
Verification results30 days
Audit logs1 year minimum
Revocation recordsIndefinite

Support Escalation

IssueContact
API errorsContact support@skippy.id
Integration helpsupport@skippy.id
Security concernssecurity@skippy.id
Status updatesstatus.skippy.id

Next Steps