FOR CS & AM TEAMS
Define the activity that matters.
Work with your developer to choose useful signals, such as logins, key feature usage, and sessions. Use the resulting account context to understand engagement and adoption.
API DOCUMENTATION · DIRECT PRODUCT INTEGRATION
If you don’t use a product analytics tool, your developer can send usage events from your backend to atEaseAI. Link logins, feature use, and sessions to customer accounts so CS and AM teams can understand usage and adoption.
For your development team · Product Usage Tracking API
Direct product usage integrationSends the usage events your developer chooses

Links activity to the right customer account
For your CS and Account Management teams
WHEN TO USE THIS API
Use this direct integration when you want to bring customer usage from your SaaS product into atEaseAI. Your development team configures your backend to send selected events; atEaseAI connects that activity to your customer accounts.
FOR CS & AM TEAMS
Work with your developer to choose useful signals, such as logins, key feature usage, and sessions. Use the resulting account context to understand engagement and adoption.
FOR YOUR DEVELOPERS
Send events from your backend using an organization API key, map them to existing customer accounts, and handle delivery and retries. The instructions below explain the setup.
Your developer chooses which product events to send through the API.
Each event is linked to the relevant customer using an account identifier.
Account-level activity supports adoption analytics and configured health metrics.
See how your team uses this context: Explore Product Adoption
GETTING STARTED
Start with a customer account you can identify reliably, then send a small test event from your backend.
Add the customer in atEaseAI and note its external ID, such as ACC-1. Use the lookup endpoint to verify the mapping.
A workspace user with the API & Webhooks permission can view the API key and API Base URL. Ask your workspace administrator if this section is unavailable.
Store the displayed API Base URL as ATEASE_API_BASE_URL and the key as ATEASE_API_KEY. The base URL shown in the app includes /api; append endpoint paths such as /usage/track.
Start with a login event. For feature adoption, define the product feature catalog and retrieve feature IDs with GET /api/usage/features.
AUTHENTICATION
For server-to-server usage integration, send your key as a Bearer token. The key identifies the organization and scopes account access to that organization.
Authorization: Bearer YOUR_API_KEY
Content-Type: application/jsonStore it in an environment variable or secret manager. Product activity from a browser or mobile app should go through your backend so the organization key stays private.
Regenerating the API key immediately invalidates the previous key. Update the services that use it before resuming event delivery.
QUICK START
Choose a server-side example. The sample sends a login event for an existing account and includes an event ID for safe retries.
# Set these in your server environment first:
# ATEASE_API_BASE_URL = API Base URL from Settings (includes /api)
# ATEASE_API_KEY = your organization API key
curl --request POST "$ATEASE_API_BASE_URL/usage/track" \
--header "Authorization: Bearer $ATEASE_API_KEY" \
--header "Content-Type: application/json" \
--data '
{
"external_id": "ACC-1",
"event_type": "login",
"user_id": "user_123",
"external_event_id": "login-event-0001",
"event_source": "web_app"
}
'// Node.js 18+ · Run on your server, not in the browser.
const baseUrl = process.env.ATEASE_API_BASE_URL.replace(/\/$/, '');
const response = await fetch(`${baseUrl}/usage/track`, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.ATEASE_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"external_id": "ACC-1",
"event_type": "login",
"user_id": "user_123",
"external_event_id": "login-event-0001",
"event_source": "web_app"
}),
});
const result = await response.json();
if (!response.ok) throw new Error(JSON.stringify(result));
console.log(result);# Server-side example · Requires the requests package.
import os
import requests
base_url = os.environ["ATEASE_API_BASE_URL"].rstrip("/")
response = requests.post(
f"{base_url}/usage/track",
headers={"Authorization": f"Bearer {os.environ['ATEASE_API_KEY']}"},
json={
"external_id": "ACC-1",
"event_type": "login",
"user_id": "user_123",
"external_event_id": "login-event-0001",
"event_source": "web_app"
},
timeout=30,
)
response.raise_for_status()
print(response.json())Code examples are provided for your backend integration. Use a new external_event_id for each distinct event; reuse it when retrying the same event.
{
"success": true,
"event_id": "8e392685-6cb6-436f-9536-0a91ed098b23",
"message": "Usage event tracked successfully"
}Accepted account events queue a health refresh. Ingestion success does not mean every derived metric or health view has refreshed immediately.
ENDPOINT REFERENCE
Each endpoint below supports an organization API key. Full paths include /api; when using the base URL from Settings, append only the path after that prefix.
/api/usage/trackTrack one eventSend one customer usage event. The account must already exist and resolve within the authenticated organization.
One event object. See the event schema below.
{
"external_id": "ACC-1",
"event_type": "login",
"user_id": "user_123",
"external_event_id": "login-event-0001",
"event_source": "web_app"
}{
"success": true,
"event_id": "8e392685-6cb6-436f-9536-0a91ed098b23",
"message": "Usage event tracked successfully"
}/api/usage/track/batchTrack a batchSend between 1 and 1,000 events. Each event is validated independently. Review all counters even when the HTTP request succeeds.
JSON object with a non-empty events array; maximum 1,000 items.
{
"events": [
{
"external_id": "ACC-1",
"event_type": "login",
"user_id": "user_123",
"external_event_id": "login-event-0001",
"event_source": "web_app"
},
{
"external_id": "ACC-1",
"event_type": "feature_used",
"user_id": "user_123",
"external_event_id": "feature-event-0001",
"metadata": {
"feature_id": "YOUR_CATALOG_FEATURE_ID"
}
}
]
}{
"success": true,
"tracked": 2,
"skipped": 0,
"duplicates": 0,
"message": "Processed 2 events, skipped 0, 0 duplicate(s)"
}/api/usage/accounts/lookupResolve an accountLook up an existing customer by external_id or account_id. Use the result to confirm that your integration maps activity to the intended account.
Query: external_id=ACC-1 (recommended), or account_id=<account UUID>.
GET /api/usage/accounts/lookup?external_id=ACC-1{
"account_id": "f1b730ce-8dfb-4cb7-a4b1-2011bcd54a80",
"external_id": "ACC-1",
"company_name": "AcmeCloud",
"primary_contact_email": "alex@example.com",
"message": "Use external_id in your usage tracking API calls (e.g., {'external_id': 'ACC-1', 'event_type': 'login'})"
}/api/usage/featuresRead the feature catalogList the features defined across the organization’s products. Use a returned feature id in metadata.feature_id when sending feature_used events.
No query parameters are required.
GET /api/usage/features{
"features": [
{
"id": "788a7c12-b8eb-49d8-a5b4-959426139c03",
"name": "Reports",
"description": "Create and review reports",
"product_id": "a77708a7-e0b3-4cf7-a98b-63f10db2b7bc",
"product_name": "Example Product"
}
],
"total": 1
}Examples show the endpoint-specific response fields. Replace example IDs, account details, and counts with your own values.
EVENT SCHEMA
The same event object is used for a single request and each item in a batch. Prefer a stable account identifier and a unique event ID from your own system.
| Field | Requirement | Purpose |
|---|---|---|
event_type | string · required | 1–100 characters. Examples: login, feature_used, session_end, or your own meaningful event name. |
external_id | string · account reference | Recommended external ID displayed on the atEaseAI account, such as ACC-1. |
account_id | string · account reference | An internal account ID can be used instead of the external ID. |
email / domain | string · alternative reference | Best-effort matching via a known contact or corporate domain. Use an explicit account ID for reliable attribution. |
external_event_id | string · recommended | Your stable ID for this event. Repeated deliveries with the same ID in the organization are treated as duplicates. |
user_id | string · recommended | Stable product user identifier, up to 200 characters. Useful for distinct-user and activation metrics. |
event_timestamp | datetime · optional | ISO 8601 event time. If omitted, the server uses the current time. Include a timezone such as Z. |
event_source | string · optional | Up to 100 characters. Defaults to product; for example, web_app. |
metadata | object · optional | Event-specific details. For feature events, use feature_id from the catalog or a known feature_name. |
Compatibility: event_data is accepted as a legacy alias for metadata. Prefer metadata in new integrations. Provider event ID aliases uuid, $insert_id, and insert_id are also recognized.
loginSend on sign-in. A matched login event also updates the account’s last-login date.
feature_usedInclude metadata.feature_id from the catalog, or a known feature_name, so usage can be connected to the feature.
session_endUse metadata.duration_seconds for session duration observations.
Your custom eventCustom names are accepted. Their impact on health depends on the configured metrics that consume those signals.
DELIVERY & LIMITS
Use stable event identifiers, inspect batch results, and keep traffic within the ingestion limits.
| Endpoint | Request limit | Limit scope |
|---|---|---|
POST /api/usage/track | 1,000 requests/hour | Per API key; per client IP when API-key authentication is not used. |
POST /api/usage/track/batch | 100 requests/hour | Per API key; maximum 1,000 events in each request. |
Reuse external_event_id for the same event. A duplicate single event returns duplicate: true; batch results include a duplicates count. Events without an ID do not have this deduplication protection.
A batch can return success: true while skipping invalid or unresolved events. Check tracked, skipped, and duplicates. The response does not identify each skipped row.
ERROR HANDLING
Successful responses are endpoint-specific. Error payloads commonly include a detail field; validation errors may return a structured list of field issues.
| Status | What it means | What to do |
|---|---|---|
| 200 | Request processed | For batches, inspect the counters as well as the HTTP status. |
| 400 | Invalid batch request | Check for a non-empty events array with at most 1,000 items. |
| 401 | Authentication failed | Check that the current organization API key is supplied as a Bearer token. |
| 403 | Access restricted | Review the workspace access and permissions relevant to the request. |
| 404 | Account not resolved | Verify the identifier with the account lookup endpoint and check its organization. |
| 422 | Payload validation failed | Check required fields, lengths, and datetime formatting. Read the field errors. |
| 429 | Request limit reached | Back off, respect Retry-After when supplied, and retry with the same event IDs. |
| 500 | Server error | Retry transient failures with bounded backoff; contact the team if failures persist. |
{
"detail": "Account not found"
}COMMON QUESTIONS
Yes. Your developer can send product usage events from your backend directly to atEaseAI. This provides account-level usage and adoption context without first connecting a product analytics tool.
Your developer or engineering team implements the server-side connection. Your CS and AM teams help decide which events and adoption signals are useful to track.
The usage endpoints in this guide resolve existing accounts. Prepare the customer account first. Separate account-management routes have their own authentication and permissions; an organization API key is not a universal credential for all application routes.
Define your products and features in atEaseAI, then call GET /api/usage/features. Use a returned id as metadata.feature_id. Catalog IDs keep your integration stable when feature names change.
A matched event is stored and queues a health refresh. Derived adoption and health views update through the evaluation process; request success is not an immediate refresh guarantee.
No. The authenticated credential determines the organization. Send the account reference and event details; customer accounts must resolve within that organization.
Tell us about your source system, account identifiers, expected event volume, and intended workflow. We can review the supported approach for your requirements.
BUILD A USEFUL CONNECTION
Bring your account identifiers, event types, and intended post-sales workflow. We can help you plan the supported integration.