# Troubleshooting Guide Solutions to common integration issues with Audit1 API # Troubleshooting Guide Common issues and solutions when integrating with Audit1 Developer API. *** ## 🔍 Quick Diagnostics ### Run This First ```bash # Test your API key curl -i -X POST https://api.audit1.info/api/v1/payroll/reports \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "employer_id": "TEST", "period_start": "2024-01-01", "period_end": "2024-03-31", "employees": [{ "employee_id": "EE_001", "name": "Test", "classification_code": "8810", "hours_worked": 520, "gross_wages": 26000 }], "payroll_data": { "total_payroll": 26000, "total_hours": 520, "officer_payroll": 0, "subcontractor_payments": 0 } }' ``` **Expected**: `HTTP/1.1 202 Accepted` with JSON response *** ## ❌ Authentication Errors ### Error: "Invalid API key format" **Symptom:** ```json { "error": "Authentication Failed", "message": "Invalid API key format. Expected audit1_test_sk_* or audit1_live_sk_*" } ``` **Causes & Solutions:** 1. **Wrong Prefix** ```bash # ❌ Wrong Authorization: Bearer sk_test_abc123... # ✅ Correct Authorization: Bearer audit1_test_sk_abc123... ``` 2. **Extra Spaces** ```bash # ❌ Wrong (space after Bearer) Authorization: Bearer audit1_test_sk_abc123... # ✅ Correct Authorization: Bearer audit1_test_sk_abc123... ``` 3. **Missing "Bearer"** ```bash # ❌ Wrong Authorization: audit1_test_sk_abc123... # ✅ Correct Authorization: Bearer audit1_test_sk_abc123... ``` 4. **Truncated Key** * Key should be ~50 characters long * Check you copied the entire key from Dashboard ### Error: "Missing Authorization header" **Symptom:** ```json { "error": "Authentication Failed", "message": "Missing Authorization header" } ``` **Solution:** ```javascript // ❌ Wrong - missing header fetch('https://api.audit1.info/api/v1/payroll/reports', { method: 'POST', body: JSON.stringify(data) }); // ✅ Correct - include Authorization fetch('https://api.audit1.info/api/v1/payroll/reports', { method: 'POST', headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' }, body: JSON.stringify(data) }); ``` ### Error: "API key not found" **Symptom:** ```json { "error": "Authentication Failed", "message": "API key not found or inactive" } ``` **Troubleshooting:** 1. Verify key exists in your portal dashboard (API Keys section) 2. Check key is marked as "Active" 3. Ensure you're using the secret key, not the key ID 4. Try creating a new key > **Portal URLs:** > > * Employers: [https://employer.audit1.info](https://employer.audit1.info) > * Payroll Companies: [https://payrollcompany.audit1.info](https://payrollcompany.audit1.info) > * Carriers: [https://carrier.audit1.info](https://carrier.audit1.info) *** ## ❌ Validation Errors ### Error: "Missing required fields" **Symptom:** ```json { "error": "Validation Error", "message": "Missing required fields: employees", "details": { "required": ["employer_id", "period_start", "period_end", "employees", "payroll_data"] } } ``` **Solution:** ```javascript // ✅ Complete payload with all required fields const payload = { employer_id: "EMP_12345", // Required period_start: "2024-01-01", // Required (YYYY-MM-DD) period_end: "2024-03-31", // Required (YYYY-MM-DD) employees: [ // Required (min 1 employee) { employee_id: "EE_001", name: "John Smith", classification_code: "8810", hours_worked: 520, gross_wages: 26000 } ], payroll_data: { // Required total_payroll: 26000, total_hours: 520, officer_payroll: 0, subcontractor_payments: 0 } }; ``` ### Error: "Invalid date format" **Symptom:** ```json { "error": "Validation Error", "message": "Invalid date format for period_start", "details": { "expected": "YYYY-MM-DD", "received": "01/15/2024" } } ``` **Solution:** ```javascript // ❌ Wrong formats "period_start": "01/15/2024" // US format "period_start": "15/01/2024" // EU format "period_start": "2024-1-15" // Missing leading zeros // ✅ Correct format "period_start": "2024-01-15" // YYYY-MM-DD ``` ### Error: "Employees array cannot be empty" **Symptom:** ```json { "error": "Validation Error", "message": "Employees array cannot be empty" } ``` **Solution:** ```javascript // ❌ Wrong - empty array "employees": [] // ❌ Wrong - null "employees": null // ✅ Correct - at least 1 employee "employees": [ { "employee_id": "EE_001", "name": "John Smith", "classification_code": "8810", "hours_worked": 520, "gross_wages": 26000 } ] ``` ### Error: "Invalid employee data" **Symptom:** ```json { "error": "Validation Error", "message": "Invalid employee data", "details": { "employees[0].classification_code": "Required field missing", "employees[1].gross_wages": "Must be a positive number" } } ``` **Employee Required Fields:** ```javascript // For payroll reports { "employee_id": "required", "name": "required", "classification_code": "required", "hours_worked": "required (number)", "gross_wages": "required (number > 0)" } // For hire action { "employee_id": "required", "action": "hire", "name": "required", "hire_date": "required (YYYY-MM-DD)", "classification_code": "required" } // For terminate action { "employee_id": "required", "action": "terminate", "termination_date": "required (YYYY-MM-DD)" } ``` *** ## ❌ Rate Limiting ### Error: "Rate limit exceeded" **Symptom:** ```json { "error": "Rate Limit Exceeded", "message": "Too many requests. Please retry after 60 seconds.", "details": { "retry_after": 60, "limit": 100, "window": "1 minute" } } ``` **Solution - Exponential Backoff:** ```javascript async function submitWithRetry(data, maxRetries = 3) { for (let i = 0; i < maxRetries; i++) { try { return await submitPayroll(data); } catch (error) { if (error.status === 429) { // Wait before retrying: 1s, 2s, 4s const delay = Math.pow(2, i) * 1000; console.log(`Rate limited. Retrying in ${delay}ms...`); await new Promise(resolve => setTimeout(resolve, delay)); } else { throw error; } } } throw new Error('Max retries exceeded'); } ``` **Solution - Batch Processing:** ```javascript async function processBatch(reports, batchSize = 10) { for (let i = 0; i < reports.length; i += batchSize) { const batch = reports.slice(i, i + batchSize); // Process batch await Promise.all(batch.map(report => submitPayroll(report))); // Wait 1 second between batches if (i + batchSize < reports.length) { await new Promise(resolve => setTimeout(resolve, 1000)); } } } ``` *** ## ❌ Connection Issues ### Error: "ECONNREFUSED" or "Network Error" **Causes:** 1. **Wrong URL** ```bash # ❌ Wrong https://developer-api.audit1.com https://sandbox-api.audit1.info # ✅ Correct https://api.audit1.info/api/v1 ``` 2. **Firewall Blocking** * Check corporate firewall * Verify outbound HTTPS is allowed * Test from different network 3. **DNS Issues** ```bash # Test DNS resolution nslookup api.audit1.info # Test connectivity ping api.audit1.info ``` ### Error: "SSL Certificate Error" **Solution:** ```javascript // ❌ Don't disable SSL verification in production! process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; // NEVER DO THIS // ✅ Update your CA certificates instead npm install -g n n latest ``` ### Timeout Errors **Solution:** ```javascript // Increase timeout const axios = require('axios'); const client = axios.create({ baseURL: 'https://api.audit1.info/api/v1', timeout: 30000, // 30 seconds headers: { 'Authorization': `Bearer ${apiKey}` } }); // Handle timeouts try { const response = await client.post('/payroll/reports', data); } catch (error) { if (error.code === 'ECONNABORTED') { console.error('Request timed out'); // Retry with longer timeout } } ``` *** ## ❌ Response Issues ### Receiving HTML Instead of JSON **Symptom:** ``` 404 Not Found ... ``` **Causes:** 1. **Wrong Endpoint** ```bash # ❌ Wrong POST /payroll-reports # ✅ Correct POST /payroll/reports ``` 2. **Missing `/api/v1` prefix** ```bash # ❌ Wrong https://api.audit1.info/payroll/reports # ✅ Correct https://api.audit1.info/api/v1/payroll/reports ``` ### Unexpected Response Format **Solution:** ```javascript // Always check response status const response = await fetch(url, options); if (!response.ok) { const error = await response.json(); console.error('API Error:', error); throw new Error(error.message); } const data = await response.json(); console.log('Success:', data); ``` *** ## ❌ Environment Issues ### Using Wrong Environment **Symptoms:** * Test data appearing in production * Production data in test environment * Unexpected report ID prefixes **Solution:** ```javascript // Clearly separate environments const config = { development: { apiKey: process.env.AUDIT1_TEST_KEY, // audit1_test_sk_* environment: 'sandbox' }, production: { apiKey: process.env.AUDIT1_LIVE_KEY, // audit1_live_sk_* environment: 'production' } }; // Select based on NODE_ENV const env = process.env.NODE_ENV || 'development'; const apiKey = config[env].apiKey; // Verify correct environment console.log(`Using ${env} environment`); console.log(`Key prefix: ${apiKey.substring(0, 16)}...`); ``` ### Can't Find Sandbox URL **Clarification:** There is **NO separate sandbox URL**. Use the same URL with different API keys: ```bash # Sandbox (test data) curl -H "Authorization: Bearer audit1_test_sk_..." \ https://api.audit1.info/api/v1/payroll/reports # Production (real data) curl -H "Authorization: Bearer audit1_live_sk_..." \ https://api.audit1.info/api/v1/payroll/reports ``` *** ## 🔧 Debugging Tools ### Enable Request Logging ```javascript // Axios interceptor axios.interceptors.request.use(request => { console.log('Request:', { method: request.method, url: request.url, headers: request.headers, data: request.data }); return request; }); axios.interceptors.response.use( response => { console.log('Response:', { status: response.status, data: response.data }); return response; }, error => { console.error('Error:', { status: error.response?.status, data: error.response?.data }); throw error; } ); ``` ### Test with cURL ```bash # Verbose output curl -v -X POST https://api.audit1.info/api/v1/payroll/reports \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d @payload.json # Save response curl -X POST https://api.audit1.info/api/v1/payroll/reports \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d @payload.json \ -o response.json # Check response headers curl -i -X POST ... ``` ### Validate JSON Payload ```bash # Use jq to validate cat payload.json | jq . # Minify JSON cat payload.json | jq -c . # Pretty print cat payload.json | jq '.' ``` *** ## 📊 Health Check ### Verify API Status 1. **Check Status Page**: [status.audit1.com](https://status.audit1.com) 2. **Test Endpoint**: Make a simple request 3. **Check Logs**: Review application logs for errors ### Self-Diagnostic Checklist ``` API Configuration: [ ] Correct base URL (https://api.audit1.info/api/v1) [ ] Valid API key format (audit1_test_sk_* or audit1_live_sk_*) [ ] Authorization header included [ ] Content-Type: application/json Request Format: [ ] Valid JSON payload [ ] All required fields present [ ] Correct date format (YYYY-MM-DD) [ ] Positive numbers for wages/hours [ ] At least 1 employee in array Network: [ ] HTTPS enabled [ ] No firewall blocking [ ] SSL certificates valid [ ] Timeout set appropriately (30s+) Error Handling: [ ] Retry logic implemented [ ] Errors logged properly [ ] Rate limiting handled [ ] Timeouts handled ``` *** ## 🆘 Still Stuck? ### Before Contacting Support 1. **Run diagnostics** from this guide 2. **Check logs** for error details 3. **Test with cURL** to isolate issue 4. **Verify API status** at [status.audit1.com](https://status.audit1.com) ### Contact Support Include this information: * **Request ID** (from response headers: `X-Request-ID`) * **Timestamp** of the error * **Full error message** and response * **API key prefix** (first 16 chars only) * **Environment** (sandbox/production) * **Sample request** (with sensitive data removed) 📧 **Email**: [support@audit1.com](mailto:support@audit1.com) *** ## 📚 Related Resources * [Getting Started Guide](https://docs.audit1.info/getting-started) * [API Reference](https://docs.audit1.info/api-reference) * [Integration Examples](https://docs.audit1.info/integration-examples) * [Quick Reference](https://docs.audit1.info/quick-reference)