async function apiCallWithRetry(apiCall, maxRetries = 3) { let retries = 0; while (retries < maxRetries) { try { return await apiCall(); } catch (error) { if (error.status === 429) { const retryAfter = error.data?.error?.retryAfter || 1; await new Promise(r => setTimeout(r, retryAfter * 1000)); retries++; continue; } if (error.status >= 400 && error.status < 500) { throw error; // Don't retry client errors } // Retry server errors with exponential backoff if (retries === maxRetries - 1) throw error; const delay = Math.pow(2, retries) * 1000 + Math.random() * 1000; await new Promise(r => setTimeout(r, delay)); retries++; } }}
Pricing Notes
All prices returned by the API are net prices excluding VAT. Each reseller is responsible for applying the applicable VAT rate based on their jurisdiction.
Always check GET /courses/{id}/terms for cancellation policies before displaying booking terms to end customers.
Security Best Practices
Store API keys in environment variables, never in client-side code
Use HTTPS for all API communications
Rotate API keys periodically
Use different API keys for development and production
Only collect the minimum player information required