DeviceInsights: MobileGator Insights Fetch API¶
The DeviceInsights API provides programmatic access to user behavior and device performance insights collected through the MobileGator SDK. This endpoint allows you to retrieve detailed analytics and metrics about device usage, performance patterns, and user engagement across mobile and web platforms.
Base URL¶
Variables¶
The following variables will be referenced throughout this documentation:
| Variable | Description | Format | Source |
|---|---|---|---|
client_id |
Unique identifier for your organization | Alphanumeric string | Provided by Credeau during onboarding |
auth_token |
Secret token for API authentication | Alphanumeric string | Provided by Credeau during onboarding |
user_id |
Unique identifier for an end user | Alphanumeric string, max 64 chars, non-PII | Generated by your application |
request_id |
Unique identifier for each API request | Alphanumeric string | Generated by Credeau API |
⚠️ Note
Keep these credentials secure and never share them publicly. These credentials are unique to your organization and will be used to authenticate all API requests.
Endpoints¶
Synchronous API¶
The synchronous endpoint processes your request immediately and returns the results in the response. Use this for real-time insights where immediate response is required.
Asynchronous API¶
The asynchronous endpoint processes the request in the background. You need to poll the same endpoint repeatedly until you receive a success response. Use this when you need guaranteed delivery of insights, especially in scenarios where network reliability might be a concern.
Authentication¶
The API requires two authentication headers:
| Header | Value |
|---|---|
x-client-id |
<client_id> |
x-auth-token |
<auth_token> |
Request Parameters¶
Request Body (JSON)¶
| Parameter | Type | Required | Description |
|---|---|---|---|
user_id |
string | Yes | Unique identifier of the user |
client_id |
string | Yes | Client identifier (must match x-client-id header) |
groupings |
array | Yes | Array of insight categories to fetch |
⚠️ Note
The
groupingsarray must contain exactly these three values:["sms", "fraud", "extracted_sms"]to generate all available features. Any other combination or format will result in incomplete insights.
Response¶
Response Fields (JSON)¶
| Field Name | Description |
|---|---|
user_id |
<user_id> |
request_id |
<request_id> |
data_requested_time |
The timestamp (in YYYY-MM-DD HH:MM:SS format) when the API request was received |
data_processed_time |
The timestamp (in YYYY-MM-DD HH:MM:SS format) when the API finished processing and returned the response |
message |
The current status of the request processing (e.g., "featurization completed", "featurization in progress", "user not found") |
<feature_name> |
One of approximately 3000 different feature values generated from the user's data, such as all_sms_count_nlp (total SMS count), txn_sms_count_nlp (transaction SMS count), or credit_sms_count_nlp (credit-related SMS count) |
message values¶
message is an important field in the response that indicates the status of api call for a user.
message Value |
Description |
|---|---|
"featurization in progress" |
Indicates that the system is currently processing and generating features for the user's data. This status is only returned by the asynchronous API endpoint while the request is being processed. |
"featurization completed" |
Indicates that all requested features have been successfully generated and are available in the response. This is the final success state for both synchronous and asynchronous API calls. |
"user not found" |
Indicates that no data has been collected for the specified user. This can occur if the user's data hasn't been synced from the MobileGator SDK or if data synchronization failed due to technical issues. |
Success Responses¶
HTTP 200 OK (Success)¶
The API returns different response structures based on the user data availability. This response structure is the same for both synchronous and asynchronous API calls.
Case 1: User Data Available
When user data is successfully processed and features are generated:
{
"user_id": "<user_id>",
"request_id": "<request_id>",
"data_requested_time": "2025-06-04 08:47:47",
"all_sms_count_nlp": 188,
"txn_sms_count_nlp": 97,
"credit_sms_count_nlp": 5,
// Additional features (approximately 3000) are included in the response
"message": "featurization completed",
"data_processed_time": "2025-06-04 08:47:50"
}
Case 2: User Data Not Available
When the API is called before user data is synced from the SDK or when data synchronization failed due to technical issues (such as network connectivity problems, app crashes, missing permissions, or abrupt app termination) -
{
"user_id": "<user_id>",
"request_id": "<request_id>",
"data_requested_time": "2025-06-04 08:47:47",
"message": "user not found",
"data_processed_time": "2025-06-04 08:47:47"
}
HTTP 202 Accepted (Async Invocation Accepted)¶
This response is specific to the asynchronous API endpoint (/api/async_insights). When the request is accepted for processing, the API returns a 202 status code with the following response structure:
{
"user_id": "<user_id>",
"request_id": "<request_id>",
"data_requested_time": "2025-06-04 08:47:47",
"message": "featurization in progress"
}
⚠️ Note
This response is only returned by the asynchronous endpoint. The synchronous endpoint (
/api/insights) will either return a 200 success response or an error response.
Error Responses¶
HTTP 401 Unauthorized (Wrong credentials)¶
This error occurs when either an invalid client ID or authentication token is provided in the request headers. The response includes a request ID that can be used for troubleshooting.
{
"error": "Could not validate credentials. (request_id=<request_id>). It has been logged successfully on our servers. Please contact us with the request_id for assistance."
}
⚠️ Note
If you receive this error:
- Verify that you're using the correct client ID and authentication token
- Contact Credeau support with the request_id for assistance
HTTP 403 Forbidden (Invalid Access)¶
This error can occur in two scenarios:
-
IP Not Whitelisted: When the requesting IP address is not whitelisted in the Credeau firewall. For security reasons, all API requests must originate from pre-approved IP addresses.
-
Incorrect API Path: When an incorrect or misspelled API path is used in the request URL. For example:
- Incorrect:
/api/insight - Correct:
/api/insights
- Incorrect:
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
</body>
</html>
⚠️ Note
To resolve this error:
- Verify that you're using the correct API endpoint path
- If the path is correct, contact Credeau support to whitelist your IP address
- Provide your organization's name and the IP address(es) that need access
- Once whitelisted, you'll be able to access the API from the approved IP addresses
HTTP 422 Unprocessable Content (Wrong Request Payload)¶
This error is returned when any of the required parameters (user_id, client_id, or groupings) is missing from the request payload. The response includes details about which fields are missing and the received input.
{
"detail": [
{
"type": "missing",
"loc": [
"body",
"user_id"
],
"msg": "Field required",
"input": {
"client_id": "<client_id>",
"groupings": [
"sms",
"fraud",
"extracted_sms"
]
}
}
]
}
HTTP 429 Too Many Requests (Rate Limit Exceeded)¶
This error is returned when the rate of requests exceeds the allowed limit of 1000 requests per minute per IP.
Best Practice for Rate Limit Handling
When implementing retries for rate-limited requests:
- Use exponential backoff: Start with a base delay (e.g., 1 second) and double it after each retry
- Add jitter: Include random variation (±20%) to the delay to prevent thundering herd problems
Example implementation:
import random
import time
def get_retry_delay(attempt, base_delay=1, max_delay=60):
# Calculate exponential backoff
delay = min(base_delay * (2 ** attempt), max_delay)
# Add jitter (±20%)
jitter = delay * 0.2
return delay + random.uniform(-jitter, jitter)
This approach helps distribute retry attempts and prevents overwhelming the API when rate limits are hit.
Example Usage¶
Synchronous API¶
cURL¶
curl --location 'https://deviceinsights.credeau.com/api/insights' \
--header 'x-client-id: <client_id>' \
--header 'x-auth-token: <auth_token>' \
--header 'Content-Type: application/json' \
--data '{
"user_id": "<user_id>",
"client_id": "<client_id>",
"groupings": ["sms", "fraud", "extracted_sms"]
}'
Python¶
import requests
import json
def fetch_insights_sync(client_id, auth_token, user_id, groupings, timeout=30):
"""
Fetch insights synchronously from the DeviceInsights API.
Args:
client_id (str): Client identifier
auth_token (str): Authentication token
user_id (str): User identifier
groupings (list): List of insight categories to fetch
timeout (int): Maximum time in seconds to wait for the response (default: 30)
Returns:
dict: The response containing insights data
Raises:
Exception: If request fails or timeout is exceeded
"""
url = "https://deviceinsights.credeau.com/api/insights"
headers = {
"x-client-id": client_id,
"x-auth-token": auth_token,
"Content-Type": "application/json"
}
payload = {
"user_id": user_id,
"client_id": client_id,
"groupings": groupings
}
response = requests.post(url, headers=headers, json=payload, timeout=timeout)
return response.json()
# Example usage
client_id = "<client_id>"
auth_token = "<auth_token>"
user_id = "<user_id>"
groupings = ["sms", "fraud", "extracted_sms"]
result = fetch_insights_sync(client_id, auth_token, user_id, groupings, timeout=30)
print(json.dumps(result, indent=2))
⚠️ Note
The
timeoutparameter should be carefully configured based on your specific use case:
- For real-time user journeys (e.g., instant loan approvals), use shorter timeouts (20-30 seconds)
- For background processing or batch operations, longer timeouts (30-60 seconds) are recommended
- Consider implementing a timeout strategy that balances user experience with system reliability
Rate Limiting -
- The API implements rate limiting with 429 (Too Many Requests) responses
- For production environments, consider implementing exponential backoff for rate-limited requests as suggested here
Asynchronous API¶
cURL¶
curl --location 'https://deviceinsights.credeau.com/api/async_insights' \
--header 'x-client-id: <client_id>' \
--header 'x-auth-token: <auth_token>' \
--header 'Content-Type: application/json' \
--data '{
"user_id": "13588589",
"client_id": "<client_id>",
"groupings": ["sms", "fraud", "extracted_sms"]
}'
Python¶
import requests
import json
import time
def fetch_insights_async(client_id, auth_token, user_id, groupings, timeout=30, max_retries=10, retry_delay=3):
"""
Fetch insights asynchronously by polling the same endpoint until success.
Args:
client_id (str): Client identifier
auth_token (str): Authentication token
user_id (str): User identifier
groupings (list): List of insight categories to fetch
timeout (int): Maximum time in seconds to wait for the response (default: 30)
max_retries (int): Maximum number of polling attempts
retry_delay (int): Delay between polling attempts in seconds
Returns:
dict: The final response containing insights data
Raises:
Exception: If max retries exceeded, overall timeout exceeded, or request fails
"""
url = "https://deviceinsights.credeau.com/api/async_insights"
headers = {
"x-client-id": client_id,
"x-auth-token": auth_token,
"Content-Type": "application/json"
}
payload = {
"user_id": user_id,
"client_id": client_id,
"groupings": groupings
}
start_time = time.time()
for attempt in range(max_retries):
# Check if we've exceeded the overall timeout
elapsed_time = time.time() - start_time
if elapsed_time >= timeout:
raise Exception(f"Overall timeout of {timeout} seconds exceeded")
try:
response = requests.post(url, headers=headers, json=payload, timeout=3)
if response.status_code == 200:
return response.json()
elif response.status_code == 202:
# Request is still processing, wait and retry
remaining_time = timeout - elapsed_time
sleep_time = min(retry_delay, remaining_time)
if sleep_time <= 0:
raise Exception(f"Overall timeout of {timeout} seconds exceeded")
time.sleep(sleep_time)
continue
elif response.status_code in [502, 504]:
# Handle gateway errors as temporary failures
remaining_time = timeout - elapsed_time
sleep_time = min(retry_delay, remaining_time)
if sleep_time <= 0:
raise Exception(f"Overall timeout of {timeout} seconds exceeded")
time.sleep(sleep_time)
continue
else:
raise Exception(f"Request failed with status {response.status_code}: {response.text}")
except requests.exceptions.Timeout:
# Handle per-request timeout
remaining_time = timeout - elapsed_time
sleep_time = min(retry_delay, remaining_time)
if sleep_time <= 0:
raise Exception(f"Overall timeout of {timeout} seconds exceeded")
time.sleep(sleep_time)
continue
except requests.exceptions.RequestException as e:
raise Exception(f"Request failed: {str(e)}")
raise Exception(f"Max retries ({max_retries}) exceeded while waiting for results")
# Example usage
client_id = "<client_id>"
auth_token = "<auth_token>"
user_id = "<user_id>"
groupings = ["sms", "fraud", "extracted_sms"]
try:
# Poll with 10 retries, 2 seconds between each attempt
result = fetch_insights_async(
client_id=client_id,
auth_token=auth_token,
user_id=user_id,
groupings=groupings,
timeout=30,
max_retries=10,
retry_delay=2
)
print(json.dumps(result, indent=2))
except Exception as e:
print(f"Error: {str(e)}")
⚠️ Note
The
timeoutparameter should be carefully configured based on your specific use case:
- For real-time user journeys (e.g., instant loan approvals), use shorter timeouts (20-30 seconds)
- For background processing or batch operations, longer timeouts (30-60 seconds) are recommended
- Consider implementing a timeout strategy that balances user experience with system reliability
Rate Limiting -
- The API implements rate limiting with 429 (Too Many Requests) responses
- For production environments, consider implementing exponential backoff for rate-limited requests as suggested here