API and AuthenticationAdmin APICustomers
List Customers
Retrieve a paginated list of customers with optional filters including parameter-based filtering
List Customers
Returns a paginated list of customers. Supports full-text search, status filtering, and filtering by customer parameters.
Endpoint
GET /customersAuthentication
Requires a valid Admin API key.
Authorization: Bearer your_api_key_hereQuery Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
limit | integer | No | Page size (1–100, default 50) |
cursor | string | No | Pagination cursor from a previous response |
search | string | No | Full-text search across name, email, phone, and customer number. Cannot be combined with parameterId or parameterName. |
status | string | No | Filter by status: active, inactive, or banned |
parameterId | string | No | Filter to customers that have this parameter set. Use the system parameter ID (e.g. system_marketing_opt_in) or the schema document ID for custom parameters. Cannot be combined with search. |
parameterName | string | No | Filter by parameter name (e.g. Marketing Opt-In). Alternative to parameterId. Cannot be combined with search. |
parameterValue | string | No | When combined with parameterId or parameterName, only return customers whose parameter matches this exact value. |
System Parameter IDs
These are the built-in system parameter IDs you can use with parameterId:
| Parameter ID | Name | Type |
|---|---|---|
system_marketing_opt_in | Marketing Opt-In | boolean ("true" / "false") |
system_sms_opt_in | SMS Opt-In | boolean ("true" / "false") |
system_date_of_birth | Date of Birth | date |
system_source | Source | select |
system_campaign | Campaign | text |
system_medium | Medium | select |
system_browser | Browser | multiselect |
system_device | Device | multiselect |
system_location | Location | select |
system_language | Language | select |
For custom parameters defined in your organization, use the parameter's schema document ID or pass the parameter name via parameterName.
Example Requests
Basic list with pagination
curl "https://api.tiquo.app/api/v1/customers?limit=25&status=active" \
-H "Authorization: Bearer your_api_key_here"Full-text search
curl "https://api.tiquo.app/api/v1/customers?search=john" \
-H "Authorization: Bearer your_api_key_here"Filter by parameter name
curl "https://api.tiquo.app/api/v1/customers?parameterName=Marketing+Opt-In¶meterValue=true" \
-H "Authorization: Bearer your_api_key_here"Filter by parameter ID
curl "https://api.tiquo.app/api/v1/customers?parameterId=system_marketing_opt_in¶meterValue=true" \
-H "Authorization: Bearer your_api_key_here"Filter by custom parameter
curl "https://api.tiquo.app/api/v1/customers?parameterName=Loyalty+Tier¶meterValue=Gold" \
-H "Authorization: Bearer your_api_key_here"Paginating through results
# First page
curl "https://api.tiquo.app/api/v1/customers?limit=10" \
-H "Authorization: Bearer your_api_key_here"
# Next page (using cursor from previous response)
curl "https://api.tiquo.app/api/v1/customers?limit=10&cursor=abc123..." \
-H "Authorization: Bearer your_api_key_here"Response
{
"success": true,
"data": [
{
"id": "k1234567890abcdef",
"customerNumber": "CUST-000001",
"firstName": "John",
"lastName": "Doe",
"displayName": "John Doe",
"emails": [
{ "address": "john@example.com", "isPrimary": true }
],
"phones": [
{ "number": "+15554567890", "isPrimary": true }
],
"profilePhoto": "https://example.com/photo.jpg",
"status": "active",
"source": "website",
"totalOrders": 15,
"totalSpent": 2450.50,
"averageOrderValue": 163.37,
"lifetimeValue": 2450.50,
"lastOrderDate": 1640995200000,
"lastActivityDate": 1640995200000,
"createdAt": 1640995200000,
"updatedAt": 1640995200000
}
],
"pagination": {
"hasMore": true,
"nextCursor": "abc123...",
"pageSize": 25
},
"timestamp": "2025-01-15T10:30:00.000Z"
}When filtering by parameter, each customer also includes a parameterValue field:
{
"success": true,
"data": [
{
"id": "k1234567890abcdef",
"customerNumber": "CUST-000001",
"firstName": "John",
"lastName": "Doe",
"displayName": "John Doe",
"emails": [
{ "address": "john@example.com", "isPrimary": true }
],
"phones": [
{ "number": "+15554567890", "isPrimary": true }
],
"status": "active",
"source": "website",
"totalOrders": 15,
"totalSpent": 2450.50,
"averageOrderValue": 163.37,
"lifetimeValue": 2450.50,
"createdAt": 1640995200000,
"updatedAt": 1640995200000,
"parameterValue": "true"
}
],
"pagination": {
"hasMore": false,
"nextCursor": null,
"pageSize": 25
},
"timestamp": "2025-01-15T10:30:00.000Z"
}Customer Object
| Field | Type | Description |
|---|---|---|
id | string | Internal document ID |
customerNumber | string | Human-readable customer ID (e.g. CUST-000001) |
firstName | string or null | Customer's first name |
lastName | string or null | Customer's last name |
displayName | string or null | Full display name |
emails | array | List of email objects with address (string) and isPrimary (boolean) |
phones | array | List of phone objects with number (string) and isPrimary (boolean) |
profilePhoto | string or null | URL to the customer's profile photo |
status | string | One of: active, inactive, banned |
source | string or null | How the customer was acquired (e.g. website, admin) |
totalOrders | integer or null | Total number of orders placed |
totalSpent | number or null | Total amount spent |
averageOrderValue | number or null | Average value per order |
lifetimeValue | number or null | Customer lifetime value |
lastOrderDate | integer or null | Unix timestamp (ms) of the last order |
lastActivityDate | integer or null | Unix timestamp (ms) of the last activity |
createdAt | integer | Unix timestamp (ms) when the record was created |
updatedAt | integer | Unix timestamp (ms) of the last update |
parameterValue | string or undefined | Only present when filtering by parameter. The matched parameter's value for this customer. |
Pagination Object
| Field | Type | Description |
|---|---|---|
hasMore | boolean | Whether more results are available |
nextCursor | string or null | Cursor to pass in the next request to get the next page |
pageSize | integer | The page size used for this request |
Error Responses
400 Bad Request
Returned when search is combined with parameter filters:
{
"success": false,
"error": "The 'search' parameter cannot be combined with parameter filters (parameterId/parameterName)",
"timestamp": "2025-01-15T10:30:00.000Z"
}401 Unauthorized
{
"success": false,
"error": "Missing or invalid API key",
"timestamp": "2025-01-15T10:30:00.000Z"
}429 Too Many Requests
{
"success": false,
"error": "Rate limit exceeded. Maximum 1,000 requests per hour.",
"timestamp": "2025-01-15T10:30:00.000Z"
}Code Examples
JavaScript
const baseUrl = 'https://api.tiquo.app/api/v1';
const headers = { 'Authorization': `Bearer ${apiKey}` };
// List all active customers
const response = await fetch(
`${baseUrl}/customers?status=active&limit=50`,
{ headers }
);
const data = await response.json();
console.log(`Found ${data.data.length} customers`);
// Filter by parameter
const marketingResponse = await fetch(
`${baseUrl}/customers?parameterName=Marketing+Opt-In¶meterValue=true`,
{ headers }
);
const marketingData = await marketingResponse.json();
console.log(`${marketingData.data.length} marketing opt-in customers`);
// Paginate through all results
let cursor = null;
let allCustomers = [];
do {
const url = new URL(`${baseUrl}/customers`);
url.searchParams.set('limit', '100');
if (cursor) url.searchParams.set('cursor', cursor);
const res = await fetch(url, { headers });
const page = await res.json();
allCustomers = allCustomers.concat(page.data);
cursor = page.pagination.nextCursor;
} while (cursor);
console.log(`Total: ${allCustomers.length} customers`);Python
import requests
base_url = 'https://api.tiquo.app/api/v1'
headers = {'Authorization': f'Bearer {api_key}'}
# List active customers
response = requests.get(
f'{base_url}/customers',
headers=headers,
params={'status': 'active', 'limit': 50}
)
data = response.json()
print(f"Found {len(data['data'])} customers")
# Filter by parameter
response = requests.get(
f'{base_url}/customers',
headers=headers,
params={
'parameterName': 'Marketing Opt-In',
'parameterValue': 'true'
}
)
data = response.json()
print(f"{len(data['data'])} marketing opt-in customers")
# Paginate through all results
all_customers = []
cursor = None
while True:
params = {'limit': 100}
if cursor:
params['cursor'] = cursor
response = requests.get(
f'{base_url}/customers',
headers=headers,
params=params
)
page = response.json()
all_customers.extend(page['data'])
if not page['pagination']['hasMore']:
break
cursor = page['pagination']['nextCursor']
print(f"Total: {len(all_customers)} customers")