GolfGlobe365 GAMP
Guides

Best Practices

API Best Practices

Follow these guidelines for optimal performance and reliability when integrating with the GG365 Golf API.

Webhook Handling

Webhooks provide real-time updates about booking status changes.

Setting Up Webhooks

Register your webhook endpoint via the API:

Code
POST /webhooks HTTP/1.1 Host: api.golfglobe365.com Content-Type: application/json X-Api-Key: your_api_key_here { "url": "https://api.youragency.example/webhooks/gg365", "events": ["booking.confirmed", "booking.cancelled", "booking.modified"], "description": "Production booking notifications" }

Webhook Handler Example

JavascriptCode
const crypto = require('crypto'); function verifyWebhookSignature(payload, signature, secret) { const hmac = crypto.createHmac('sha256', secret); const digest = hmac.update(payload).digest('hex'); return crypto.timingSafeEqual(Buffer.from(digest), Buffer.from(signature)); } app.post('/webhooks/gg365', (req, res) => { const signature = req.headers['x-gg-signature']; if (!verifyWebhookSignature(JSON.stringify(req.body), signature, WEBHOOK_SECRET)) { return res.status(401).send('Invalid signature'); } const event = req.body; switch (event.type) { case 'booking.confirmed': updateBookingStatus(event.data.bookingId, 'confirmed'); break; case 'booking.cancelled': updateBookingStatus(event.data.bookingId, 'cancelled'); break; case 'booking.modified': syncBookingDetails(event.data.bookingId); break; } res.status(200).send('OK'); });

Webhook Event Types

Event TypeDescription
booking.confirmedBooking confirmed by the golf course
booking.cancelledBooking has been cancelled
booking.modifiedBooking details have been modified
refund.processedRefund has been processed

Caching Strategies

DataRecommended TTLNotes
Course details24 hoursCourse info rarely changes
Course pricing24 hoursUpdates seasonally
Tee time availability5 minutesChanges rapidly
Booking details1 hourMay be modified or cancelled

Error Handling and Retries

JavascriptCode
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
Last modified on