Troubleshooting 
This guide helps you diagnose and fix common issues with your PocketDNS integration.
Common Issues 
API Authentication Problems 
Issue: Getting 401 Unauthorized errors
Symptoms:
{
  "error": "unauthorized",
  "message": "Invalid API key"
}Solutions:
- Check API Key Format - Sandbox keys start with sk_sandbox_
- Production keys start with sk_live_
 bash- echo $POCKETDNS_API_KEY | cut -c1-11 # Should output: sk_sandbox_ or sk_live_
- Sandbox keys start with 
- Verify Environment Variables javascript- console.log('API Key set:', !!process.env.POCKETDNS_API_KEY); console.log('API Key prefix:', process.env.POCKETDNS_API_KEY?.substring(0, 11));
- Check API Endpoint javascript- const config = { sandbox: 'https://api.sandbox.pocketdns.com', production: 'https://api.pocketdns.com' }; // Ensure you're using the right endpoint for your API key
- Test API Key bash- curl -H "Authorization: Bearer YOUR_API_KEY" \ https://api.sandbox.pocketdns.com/api/v1/health
Session Creation Failures 
Issue: User session creation failing
Symptoms:
- Empty or invalid login URLs
- Sessions expiring immediately
- Users can't access the embed interface
Solutions:
- Validate User Identifier javascript- const validateUserIdentifier = (identifier) => { if (!identifier || typeof identifier !== 'string') { throw new Error('User identifier must be a non-empty string'); } if (identifier.length > 255) { throw new Error('User identifier too long (max 255 chars)'); } if (!/^[a-zA-Z0-9_-]+$/.test(identifier)) { throw new Error('User identifier can only contain letters, numbers, underscores, and hyphens'); } return identifier; };
- Check Session Response javascript- const session = await createUserSession('user_123'); console.log('Session created:', { hasLoginUrl: !!session.login_url, expiresAt: session.expires_at, isExpired: new Date(session.expires_at) < new Date() });
- Verify Email Format (if provided) javascript- const validateEmail = (email) => { if (!email) return null; // Email is optional const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (!emailRegex.test(email)) { throw new Error('Invalid email format'); } return email; };
Iframe Loading Issues 
Issue: Embedded iframe not loading or displaying errors
Symptoms:
- Blank iframe
- "This site can't be reached" errors
- CORS errors in console
- Iframe shows error page
Solutions:
- Check Login URL Validity javascript- const validateLoginUrl = (loginUrl) => { try { const url = new URL(loginUrl); const expectedHost = process.env.NODE_ENV === 'production' ? 'embed.pocketdns.com' : 'embed.sandbox.pocketdns.com'; if (url.hostname !== expectedHost) { console.warn(`Unexpected embed host: ${url.hostname}`); } return true; } catch (error) { console.error('Invalid login URL:', error); return false; } };
- Verify Iframe Configuration html- <!-- Ensure iframe has required attributes --> <iframe src="{login_url}" width="100%" height="600px" frameborder="0" allow="payment" sandbox="allow-scripts allow-same-origin allow-forms allow-popups" title="PocketDNS Domain Interface"> </iframe>
- Check CORS and CSP Settings html- <!-- Add to your page head if needed --> <meta http-equiv="Content-Security-Policy" content="frame-src embed.pocketdns.com embed.sandbox.pocketdns.com;">
- Debug Network Issues javascript- // Test if embed URL is reachable const testEmbedUrl = async (loginUrl) => { try { const response = await fetch(loginUrl, { method: 'HEAD' }); console.log('Embed URL status:', response.status); return response.ok; } catch (error) { console.error('Embed URL unreachable:', error); return false; } };
DNS Record Issues 
Issue: DNS records not working as expected
Symptoms:
- DNS records not propagating
- Website not accessible after DNS changes
- Email not working with MX records
Solutions:
- Validate DNS Record Format javascript- const validateDNSRecord = (record) => { const validators = { A: (content) => /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(content), AAAA: (content) => /^[0-9a-fA-F:]+$/.test(content), CNAME: (content) => /^[a-zA-Z0-9.-]+$/.test(content), MX: (content) => /^\d+ [a-zA-Z0-9.-]+$/.test(content), TXT: () => true // TXT records can contain any text }; const validator = validators[record.type]; if (!validator || !validator(record.content)) { throw new Error(`Invalid ${record.type} record content: ${record.content}`); } return true; };
- Check DNS Propagation bash- # Check if DNS records are propagating dig @8.8.8.8 example.com A dig @1.1.1.1 example.com A # Check from multiple locations nslookup example.com 8.8.8.8
- Verify TTL Settings javascript- const recommendedTTLs = { A: 300, // 5 minutes AAAA: 300, // 5 minutes CNAME: 300, // 5 minutes MX: 3600, // 1 hour TXT: 300 // 5 minutes }; const checkTTL = (record) => { const recommended = recommendedTTLs[record.type]; if (record.ttl > recommended * 4) { console.warn(`High TTL for ${record.type} record: ${record.ttl}s (recommended: ${recommended}s)`); } };
Rate Limiting Issues 
Issue: Getting 429 "Too Many Requests" errors
Symptoms:
{
  "error": "rate_limit_exceeded",
  "message": "Too many requests",
  "details": {
    "limit": 100,
    "window": 60,
    "retry_after": 30
  }
}Solutions:
- Implement Rate Limit Handling javascript- const handleRateLimit = async (operation, maxRetries = 3) => { for (let attempt = 0; attempt < maxRetries; attempt++) { try { return await operation(); } catch (error) { if (error.status === 429 && attempt < maxRetries - 1) { const retryAfter = error.details?.retry_after || Math.pow(2, attempt); console.log(`Rate limited. Retrying in ${retryAfter} seconds...`); await new Promise(resolve => setTimeout(resolve, retryAfter * 1000)); continue; } throw error; } } };
- Add Request Caching javascript- const cache = new Map(); const CACHE_TTL = 5 * 60 * 1000; // 5 minutes const cachedApiCall = async (key, apiCall) => { const cached = cache.get(key); if (cached && Date.now() - cached.timestamp < CACHE_TTL) { return cached.data; } const data = await apiCall(); cache.set(key, { data, timestamp: Date.now() }); return data; };
- Monitor Rate Limit Usage javascript- const trackRateLimit = (response) => { const limit = response.headers.get('X-RateLimit-Limit'); const remaining = response.headers.get('X-RateLimit-Remaining'); const reset = response.headers.get('X-RateLimit-Reset'); console.log(`Rate limit: ${remaining}/${limit} remaining, resets at ${new Date(reset * 1000)}`); if (remaining < 10) { console.warn('Approaching rate limit!'); } };
Webhook Issues 
Issue: Webhooks not being received or processed
Symptoms:
- Missing webhook notifications
- Webhook signature verification failures
- Webhook endpoint returning errors
Solutions:
- Verify Webhook Endpoint bash- # Test if your webhook endpoint is accessible curl -X POST https://yourdomain.com/webhook/pocketdns \ -H "Content-Type: application/json" \ -d '{"test": "payload"}'
- Check Webhook Signature Verification javascript- const crypto = require('crypto'); const verifyWebhookSignature = (payload, signature, secret) => { if (!signature || !signature.startsWith('sha256=')) { console.error('Missing or invalid signature format'); return false; } const expectedSignature = crypto .createHmac('sha256', secret) .update(payload, 'utf8') .digest('hex'); const receivedSignature = signature.replace('sha256=', ''); return crypto.timingSafeEqual( Buffer.from(expectedSignature, 'hex'), Buffer.from(receivedSignature, 'hex') ); };
- Debug Webhook Processing javascript- app.post('/webhook/pocketdns', (req, res) => { console.log('Webhook received:', { headers: req.headers, body: req.body, timestamp: new Date().toISOString() }); try { // Process webhook res.status(200).json({ received: true }); } catch (error) { console.error('Webhook processing failed:', error); res.status(500).json({ error: error.message }); } });
Diagnostic Tools 
API Health Check 
const checkAPIHealth = async () => {
  const checks = {
    apiConnectivity: false,
    authentication: false,
    userCreation: false,
    domainRetrieval: false
  };
  
  try {
    // Test API connectivity
    const healthResponse = await fetch('https://api.pocketdns.com/health');
    checks.apiConnectivity = healthResponse.ok;
    
    // Test authentication
    const authResponse = await fetch('https://api.pocketdns.com/api/v1/users', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${process.env.POCKETDNS_API_KEY}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        user_identifier: 'health_check_user',
        email: '[email protected]'
      })
    });
    checks.authentication = authResponse.status !== 401;
    checks.userCreation = authResponse.ok;
    
    // Test domain retrieval
    const domainResponse = await fetch(
      'https://api.pocketdns.com/api/v1/users/health_check_user/domains',
      {
        headers: {
          'Authorization': `Bearer ${process.env.POCKETDNS_API_KEY}`
        }
      }
    );
    checks.domainRetrieval = domainResponse.ok || domainResponse.status === 404;
    
  } catch (error) {
    console.error('Health check error:', error);
  }
  
  return checks;
};Configuration Validator 
const validateConfiguration = () => {
  const issues = [];
  
  // Check environment variables
  if (!process.env.POCKETDNS_API_KEY) {
    issues.push('POCKETDNS_API_KEY environment variable not set');
  } else {
    const key = process.env.POCKETDNS_API_KEY;
    if (!key.startsWith('sk_sandbox_') && !key.startsWith('sk_live_')) {
      issues.push('POCKETDNS_API_KEY has invalid format');
    }
    
    if (process.env.NODE_ENV === 'production' && key.startsWith('sk_sandbox_')) {
      issues.push('Using sandbox API key in production environment');
    }
  }
  
  // Check webhook configuration
  if (!process.env.POCKETDNS_WEBHOOK_SECRET) {
    issues.push('POCKETDNS_WEBHOOK_SECRET environment variable not set');
  }
  
  // Check HTTPS
  if (process.env.NODE_ENV === 'production' && process.env.DISABLE_HTTPS !== 'true') {
    // Add HTTPS checks here
  }
  
  return {
    valid: issues.length === 0,
    issues
  };
};Network Diagnostics 
const diagnoseNetworkIssues = async () => {
  const tests = {
    dns: false,
    connectivity: false,
    latency: null,
    ssl: false
  };
  
  try {
    // Test DNS resolution
    const dns = require('dns').promises;
    await dns.resolve('api.pocketdns.com');
    tests.dns = true;
    
    // Test connectivity and measure latency
    const start = Date.now();
    const response = await fetch('https://api.pocketdns.com/health', {
      timeout: 10000
    });
    tests.latency = Date.now() - start;
    tests.connectivity = response.ok;
    tests.ssl = response.url.startsWith('https://');
    
  } catch (error) {
    console.error('Network diagnostic error:', error);
  }
  
  return tests;
};Debug Mode 
Enable debug mode for verbose logging:
const DEBUG = process.env.DEBUG === 'pocketdns' || process.env.NODE_ENV === 'development';
const debugLog = (...args) => {
  if (DEBUG) {
    console.log('[PocketDNS Debug]', new Date().toISOString(), ...args);
  }
};
// Usage throughout your code
debugLog('Creating user session for:', userIdentifier);
debugLog('API response:', response.status, response.headers);
debugLog('Session created:', session);Getting Help 
Information to Collect 
When reporting issues, collect this information:
const collectDiagnosticInfo = async () => {
  const info = {
    timestamp: new Date().toISOString(),
    environment: process.env.NODE_ENV,
    nodeVersion: process.version,
    apiKeyPrefix: process.env.POCKETDNS_API_KEY?.substring(0, 11) || 'not-set',
    configuration: validateConfiguration(),
    apiHealth: await checkAPIHealth(),
    networkDiagnostics: await diagnoseNetworkIssues()
  };
  
  return info;
};