Skip to main content
Follow these guidelines to build integrations that are reliable, secure, and maintainable.

Architecture

Use webhooks instead of polling

Instead of repeatedly calling the API to check for changes, subscribe to webhook events. This is more efficient and gives you real-time updates.
Polling (bad):   GET /contacts/ every 30 seconds
Webhooks (good): Receive ContactCreate event instantly

Implement idempotency

Design your handlers to be safe when called multiple times with the same data. Webhooks can be delivered more than once, and network issues may cause you to retry API calls.
// Use upsert instead of create to avoid duplicates
const response = await hoopai('/contacts/upsert', {
  method: 'POST',
  body: {
    locationId: 'LOC_ID',
    email: 'jane@example.com',
    firstName: 'Jane',
    lastName: 'Smith'
  }
});

Handle pagination for large datasets

Never assume all results fit in a single response. Always paginate through results:
def get_all_contacts(api):
    all_contacts = []
    page = 1

    while True:
        result = api.get('/contacts/', limit=100, page=page)
        all_contacts.extend(result['contacts'])

        if not result['meta'].get('nextPage'):
            break
        page = result['meta']['nextPage']

    return all_contacts

Error handling

Retry with exponential backoff

For transient errors (429, 500, 502, 503), retry with increasing delays:
AttemptWait time
11 second
22 seconds
34 seconds
48 seconds
5Give up, log, and alert

Distinguish error types

Error typeStatus codesAction
Client error400, 422Fix the request — don’t retry
Auth error401, 403Refresh token or re-authorize
Rate limit429Wait and retry using X-RateLimit-Reset
Server error5xxRetry with backoff

Security

Token management

  • Never expose tokens in client-side code — always make API calls from your server
  • Store tokens encrypted in your database or secrets manager
  • Implement automatic token refresh before expiration, not after
  • Rotate Private Integration keys periodically

Webhook security

  • Always verify webhook signatures before processing payloads
  • Validate the locationId in webhook payloads matches a known installation
  • Use HTTPS for all webhook endpoints
  • Set a timeout — reject requests that take too long

Data handling

  • Only request and store the data your integration needs
  • Respect user privacy and comply with applicable regulations (GDPR, CCPA)
  • Clean up stored data when your app is uninstalled

Performance

Batch operations

Where available, use bulk endpoints instead of making individual requests:
# Instead of creating contacts one at a time, use bulk tag update
POST /contacts/bulk/tags/update/add
{
  "locationId": "LOC_ID",
  "contactIds": ["id1", "id2", "id3"],
  "tags": ["imported"]
}

Cache frequently accessed data

Cache reference data that doesn’t change often:
  • Pipeline stages
  • Calendar configurations
  • Custom field definitions
  • User/team member lists

Use efficient queries

  • Always specify limit to control response size
  • Use search endpoints with filters instead of fetching all records and filtering locally
  • Request only the fields you need (where supported)

Monitoring

  • Log all API calls including response status, latency, and rate limit headers
  • Track webhook deliveries and monitor for failures
  • Set up alerts for elevated error rates or authentication failures
  • Monitor token refresh cycles to catch issues before they affect users

Next steps

Last modified on March 5, 2026