> ## Documentation Index
> Fetch the complete documentation index at: https://help.hoopai.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Best practices

> Recommendations for building robust, performant, and secure integrations with HoopAI.

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](/developer/guide/webhooks). 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.

```javascript theme={null}
// 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:

```python theme={null}
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:

| Attempt | Wait time               |
| ------- | ----------------------- |
| 1       | 1 second                |
| 2       | 2 seconds               |
| 3       | 4 seconds               |
| 4       | 8 seconds               |
| 5       | Give up, log, and alert |

### Distinguish error types

| Error type   | Status codes | Action                                   |
| ------------ | ------------ | ---------------------------------------- |
| Client error | `400`, `422` | Fix the request — don't retry            |
| Auth error   | `401`, `403` | Refresh token or re-authorize            |
| Rate limit   | `429`        | Wait and retry using `X-RateLimit-Reset` |
| Server error | `5xx`        | Retry 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:

```bash theme={null}
# 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

<CardGroup cols={2}>
  <Card title="API reference" icon="terminal" href="/api-reference/introduction">
    Explore all available endpoints
  </Card>

  <Card title="Webhook events" icon="bell" href="/api-reference/webhooks/overview">
    Full list of event types and payloads
  </Card>
</CardGroup>
