Authentication & Basics
Base URL, authentication, rate limiting, pagination, and error handling.
Authentication & Basics
Base URL
All API requests use your account’s domain followed by the versioned API path:
https://your-domain.com/api/v1/
Replace your-domain.com with your actual application URL.
Authentication
Every request must include a valid API token in the Authorization header. The token determines which account context and permissions are active.
Authorization: Bearer YOUR_API_TOKEN
Accept: application/json
Always include the Accept: application/json header to ensure you receive JSON responses.
Example Request
curl -X GET "https://your-domain.com/api/v1/contacts" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"const response = await fetch("https://your-domain.com/api/v1/contacts", {
headers: {
"Authorization": "Bearer YOUR_API_TOKEN",
"Accept": "application/json"
}
});
const data = await response.json();$ch = curl_init('https://your-domain.com/api/v1/contacts');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_TOKEN',
'Accept: application/json',
],
]);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);import requests
response = requests.get(
"https://your-domain.com/api/v1/contacts",
headers={
"Authorization": "Bearer YOUR_API_TOKEN",
"Accept": "application/json"
}
)
data = response.json()Tenant Scoping
All API requests are automatically scoped to the membership (account) associated with the token. You cannot access data from other accounts, even with a valid token.
Rate Limiting
Each token has a rate limit (default: 60 requests per minute). Custom rate limits can be set per token. Response headers indicate your current usage:
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests allowed per minute |
X-RateLimit-Remaining | Requests remaining in the current window |
Retry-After | Seconds to wait before retrying (only on 429 responses) |
Pagination
All list endpoints return paginated results. Use page and per_page query parameters to navigate. Default is 25 per page, maximum is 100.
GET /api/v1/contacts?page=2&per_page=10
Paginated responses include meta and links objects:
{
"data": [ ... ],
"meta": {
"current_page": 2,
"last_page": 5,
"per_page": 10,
"total": 48
},
"links": {
"first": "https://your-domain.com/api/v1/contacts?page=1",
"last": "https://your-domain.com/api/v1/contacts?page=5",
"prev": "https://your-domain.com/api/v1/contacts?page=1",
"next": "https://your-domain.com/api/v1/contacts?page=3"
}
}
Error Responses
The API uses standard HTTP status codes. Errors return a JSON body with a message field:
| Status | Meaning | When |
|---|---|---|
401 | Unauthorized | Missing, invalid, or expired token |
403 | Forbidden | Token lacks the required ability for this endpoint |
404 | Not Found | Resource does not exist or belongs to a different account |
422 | Unprocessable Entity | Validation errors |
429 | Too Many Requests | Rate limit exceeded |
500 | Internal Server Error | Unexpected server error |
Validation Error Format (422)
{
"message": "The first name field is required.",
"errors": {
"first_name": [
"The first name field is required."
]
}
}
Was this article helpful?