- Developers
- Getting started
Pagination and errors
Handle cursor-based pagination and interpret standard error responses.
The HowdyBell API uses cursor-based pagination for list endpoints. This approach is efficient for large datasets and avoids the issues associated with offset-based pagination.
Cursor-Based Pagination
List endpoints such as List contacts and List conversations return a next_cursor field. Use this cursor to fetch the next page of results.
Response Structure
{
"data": [
{ "id": 1, "first_name": "Jane" },
{ "id": 2, "first_name": "John" }
],
"next_cursor": "eyJwYWdlIjoyfQ",
"total": 150
}
data: An array of objects for the current page.next_cursor: A string token for the next page. Ifnull, there are no more results.total: The total number of matching records.
Fetching the Next Page
Pass the next_cursor value as the cursor query parameter.
curl -X GET "https://howdybell.com/api/v1/contacts?location_id=101&cursor=eyJwYWdlIjoyfQ" \
-H "Authorization: Bearer hb_live_your_key_here"
Pagination Limits
- The default page size is 200 items.
- You cannot change the page size via query parameters.
- Cursors are opaque strings. Do not attempt to decode or modify them.
Error Responses
All errors return a JSON body with a consistent structure. The HTTP status code indicates the type of error.
401 Unauthorized
Returned when authentication fails.
{
"error": "invalid_api_key"
}
404 Not Found
Returned when a resource does not exist or is not accessible.
{
"error": "contact.not_found"
}
Common 404 errors include:
location.not_found: Invalid or out-of-workspace location ID.contact.not_found: Contact ID does not exist in the specified location.tag.not_found: Tag ID does not exist in the workspace.
422 Unprocessable Entity
Returned when request validation fails.
{
"message": "The first name field is required.",
"errors": {
"first_name": [
"The first name field is required."
]
}
}
429 Too Many Requests
Returned when you exceed the rate limit.
{
"message": "Too Many Attempts."
}
The response carries a Retry-After header with the number of seconds to wait.
Error Handling Best Practices
- Check Status Codes: Always inspect the HTTP status code before parsing the body.
- Log Error Bodies: Include the full JSON body in your logs for debugging.
- Retry on 429: Wait the number of seconds in the
Retry-Afterheader, then try again. - Handle 404s Gracefully: Do not treat
404errors as fatal if the resource may have been deleted. - Validate Inputs: Check required fields before sending requests to avoid
422errors.
Example: Robust Pagination Loop
async function fetchAllContacts(locationId, apiKey) {
let cursor = null;
let allContacts = [];
do {
let url = `https://howdybell.com/api/v1/contacts?location_id=${locationId}`;
if (cursor) {
url += `&cursor=${encodeURIComponent(cursor)}`;
}
const response = await fetch(url, {
headers: {
'Authorization': `Bearer ${apiKey}`,
'Accept': 'application/json'
}
});
if (!response.ok) {
throw new Error(`API error: ${response.status}`);
}
const data = await response.json();
allContacts = allContacts.concat(data.data);
cursor = data.next_cursor;
} while (cursor);
return allContacts;
}
Note: The
totalfield is provided for informational purposes. Do not rely on it to determine when to stop paginating. Always checknext_cursor.