Skip to content

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

https://deviceinsights.credeau.com

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

POST /api/insights

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

POST /api/async_insights

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 groupings array 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:

  1. Verify that you're using the correct client ID and authentication token
  2. Contact Credeau support with the request_id for assistance

HTTP 403 Forbidden (Invalid Access)

This error can occur in two scenarios:

  1. 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.

  2. Incorrect API Path: When an incorrect or misspelled API path is used in the request URL. For example:

    • Incorrect: /api/insight
    • Correct: /api/insights
<html>
    <head><title>403 Forbidden</title></head>
    <body>
        <center><h1>403 Forbidden</h1></center>
    </body>
</html>

⚠️ Note

To resolve this error:

  1. Verify that you're using the correct API endpoint path
  2. If the path is correct, contact Credeau support to whitelist your IP address
  3. Provide your organization's name and the IP address(es) that need access
  4. 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:

  1. Use exponential backoff: Start with a base delay (e.g., 1 second) and double it after each retry
  2. 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 timeout parameter 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 timeout parameter 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