Usage & Analytics
The ONE SDK provides a dedicated UsageService for tracking API consumption, monitoring quotas, and reviewing usage analytics. You can view usage data in the dashboard or query it programmatically.
Creating a UsageService
The SDK offers two factory functions for creating the service.
createUsageService
Create a new UsageService instance with explicit configuration.
import { createUsageService } from '@one_deploy/sdk';
const usageService = createUsageService({
engineUrl: process.env.ONE_ENGINE_URL!,
clientId: process.env.ONE_CLIENT_ID!,
secretKey: process.env.ONE_SECRET_KEY!,
projectId: 'proj_abc123',
});
getUsageService
Retrieve a singleton UsageService instance that reuses the configuration from the current OneEngineClient context.
import { getUsageService } from '@one_deploy/sdk';
const usageService = getUsageService();
When using getUsageService() inside a React component, the service automatically inherits configuration from the nearest OneProvider. No additional setup is needed.
Types
UsageCategory
Categorises the type of API call being tracked.
type UsageCategory =
| 'auth'
| 'wallet'
| 'swap'
| 'onramp'
| 'offramp'
| 'ai_trading'
| 'forex'
| 'contracts'
| 'nfts'
| 'billing'
| 'staking'
| 'bridge'
| 'gas'
| 'price'
| 'webhooks'
| 'admin'
| 'project';
DisplayCategory
A higher-level grouping used in the dashboard UI charts and tables.
type DisplayCategory =
| 'Authentication'
| 'Wallet & Assets'
| 'Payments'
| 'Trading'
| 'Infrastructure'
| 'Management';
UsageRecord
A single usage data point representing a time-bucketed count.
interface UsageRecord {
id: string;
projectId: string;
category: UsageCategory;
count: number;
timestamp: string; // ISO-8601
metadata?: Record<string, unknown>;
}
UsageSummary
Aggregated usage totals for a project within a given time range.
interface UsageSummary {
projectId: string;
totalCalls: number;
byCategory: Record<UsageCategory, number>;
byDisplayCategory: Record<DisplayCategory, number>;
periodStart: string; // ISO-8601
periodEnd: string; // ISO-8601
quotaLimit: number;
quotaUsed: number;
quotaRemaining: number;
}
UsageActivity
A timestamped activity entry for the usage feed.
interface UsageActivity {
id: string;
projectId: string;
category: UsageCategory;
action: string; // e.g. "swap.execute", "wallet.getBalance"
timestamp: string; // ISO-8601
statusCode: number;
durationMs: number;
metadata?: Record<string, unknown>;
}
UsageResponse
The standard envelope returned by usage query methods.
interface UsageResponse<T> {
success: boolean;
data?: T;
error?: string;
meta?: {
page: number;
limit: number;
total: number;
};
}
Tracking API Usage
Get Usage Summary
Retrieve an aggregated summary for a project over a specified time range.
const summary = await usageService.getUsageSummary({
projectId: 'proj_abc123',
from: '2025-01-01T00:00:00Z',
to: '2025-01-31T23:59:59Z',
});
if (summary.success) {
const data: UsageSummary = summary.data;
console.log('Total API calls:', data.totalCalls);
console.log('Quota used:', data.quotaUsed, '/', data.quotaLimit);
console.log('Remaining:', data.quotaRemaining);
// Breakdown by category
for (const [category, count] of Object.entries(data.byCategory)) {
console.log(` ${category}: ${count} calls`);
}
}
Get Usage Records
Fetch granular, time-bucketed usage records for charting and detailed analysis.
const records = await usageService.getUsageRecords({
projectId: 'proj_abc123',
category: 'ai_trading',
from: '2025-01-01T00:00:00Z',
to: '2025-01-31T23:59:59Z',
granularity: 'day', // 'hour' | 'day' | 'week' | 'month'
page: 1,
limit: 31,
});
if (records.success) {
for (const record of records.data) {
console.log(`${record.timestamp}: ${record.count} calls`);
}
}
Get Usage Activity Feed
Retrieve a chronological feed of individual API calls for debugging and auditing.
const activity = await usageService.getUsageActivity({
projectId: 'proj_abc123',
category: 'wallet',
page: 1,
limit: 50,
});
if (activity.success) {
for (const entry of activity.data) {
console.log(
`[${entry.timestamp}] ${entry.action} -- ${entry.statusCode} (${entry.durationMs}ms)`
);
}
}
Viewing Analytics in the Dashboard
The dashboard at dashboard.one23.io provides a visual analytics view with:
- Volume chart -- daily and hourly API call volume over the selected time range.
- Category breakdown -- pie or bar chart showing the distribution of calls across
DisplayCategorygroups. - Top endpoints -- ranked list of the most frequently called API methods.
- Error rate -- percentage of calls returning 4xx or 5xx status codes.
- Latency percentiles -- p50, p95, and p99 response times across all endpoints.
Quotas and Rate Limits
Each project plan has a monthly API call quota and per-second rate limits.
| Plan | Monthly Quota | Rate Limit (req/s) |
|---|---|---|
| Free | 10,000 | 10 |
| Pro | 500,000 | 100 |
| Enterprise | Custom | Custom |
Checking Quota Status
const summary = await usageService.getUsageSummary({
projectId: 'proj_abc123',
from: new Date(new Date().getFullYear(), new Date().getMonth(), 1).toISOString(),
to: new Date().toISOString(),
});
if (summary.success) {
const { quotaLimit, quotaUsed, quotaRemaining } = summary.data;
const usagePercent = ((quotaUsed / quotaLimit) * 100).toFixed(1);
console.log(`Usage: ${quotaUsed} / ${quotaLimit} (${usagePercent}%)`);
console.log(`Remaining: ${quotaRemaining}`);
if (quotaRemaining < quotaLimit * 0.1) {
console.warn('Warning: Less than 10% of your monthly quota remains.');
}
}
Rate Limit Headers
When a request is rate-limited, the API returns a 429 Too Many Requests status with the following headers:
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests allowed per second for your plan. |
X-RateLimit-Remaining | Remaining requests in the current window. |
X-RateLimit-Reset | Unix timestamp (seconds) when the rate limit window resets. |
Retry-After | Number of seconds to wait before retrying. |
Handling Rate Limits
async function callWithRetry<T>(
fn: () => Promise<UsageResponse<T>>,
maxRetries: number = 3
): Promise<UsageResponse<T>> {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
const res = await fn();
if (res.success || res.error !== 'rate_limited') {
return res;
}
// Exponential backoff: 1s, 2s, 4s
const delay = Math.pow(2, attempt) * 1000;
console.warn(`Rate limited. Retrying in ${delay}ms...`);
await new Promise((resolve) => setTimeout(resolve, delay));
}
return { success: false, error: 'Max retries exceeded' };
}
Full Example
import { createUsageService } from '@one_deploy/sdk';
const usageService = createUsageService({
engineUrl: process.env.ONE_ENGINE_URL!,
clientId: process.env.ONE_CLIENT_ID!,
secretKey: process.env.ONE_SECRET_KEY!,
projectId: 'proj_abc123',
});
async function generateMonthlyReport() {
const now = new Date();
const monthStart = new Date(now.getFullYear(), now.getMonth(), 1);
// 1. Summary
const summary = await usageService.getUsageSummary({
projectId: 'proj_abc123',
from: monthStart.toISOString(),
to: now.toISOString(),
});
if (!summary.success) {
console.error('Failed to fetch summary:', summary.error);
return;
}
console.log('=== Monthly Usage Report ===');
console.log(`Period: ${summary.data.periodStart} to ${summary.data.periodEnd}`);
console.log(`Total calls: ${summary.data.totalCalls}`);
console.log(`Quota: ${summary.data.quotaUsed} / ${summary.data.quotaLimit}`);
// 2. Category breakdown
console.log('\n--- By Category ---');
for (const [cat, count] of Object.entries(summary.data.byCategory)) {
if (count > 0) {
console.log(` ${cat}: ${count}`);
}
}
// 3. Daily records for the top category
const topCategory = Object.entries(summary.data.byCategory)
.sort(([, a], [, b]) => b - a)[0];
if (topCategory) {
const records = await usageService.getUsageRecords({
projectId: 'proj_abc123',
category: topCategory[0] as any,
from: monthStart.toISOString(),
to: now.toISOString(),
granularity: 'day',
});
if (records.success) {
console.log(`\n--- Daily Breakdown: ${topCategory[0]} ---`);
for (const record of records.data) {
console.log(` ${record.timestamp}: ${record.count}`);
}
}
}
}
generateMonthlyReport();
Next Steps
- Webhook Configuration -- set up event-driven notifications.
- Team Management -- control who can view usage data.
- API Keys -- manage project credentials.