Skip to content
On this page

Reference

TypeScript types

Copy-ready types for the responses used across the dashboard.

These are the same shapes the dashboard uses. They are intentionally permissive where the backend can return provider-specific values.

export type Micro = number; // 1_000_000 = $1
export interface TokenResponse {
token: string;
user_id: string;
}
export interface Me {
id: string;
email: string;
created_at: number;
email_verified: boolean;
role: 'user' | 'admin';
is_admin: boolean;
balance_micro: Micro;
balance_usd: number;
network_fee_micro: number; // -1 = model default, 0 = waived, >0 = custom
}
export interface KeyResponse {
id: string;
name: string;
prefix: string;
created_at: number;
expires_at: number | null;
rpm_limit: number;
conc_limit: number;
daily_cap_micro: Micro;
monthly_cap_micro: Micro;
allow_fallback: boolean;
byok_provider: string | null;
byok_base_url: string | null;
key: string | null; // only on create/rotate
}
export interface ModelPricing {
prompt: number; // USD / 1M (billed)
completion: number; // USD / 1M (billed)
token_multiplier: number;
fixed_micro: Micro;
image_micro: Micro;
audio_min_micro: Micro;
video_sec_micro: Micro;
official_prompt: number; // upstream reference (0 = unknown)
official_completion: number;
discount_pct: number; // configured discount (0-100)
discount_fiat_micro: Micro;// flat micro-USD per 1M tokens removed
saved_pct: number; // effective saving for badges
}
export interface Model {
id: string;
name: string;
created: number;
description: string;
modality: string;
supports_cache: boolean;
context_length: number;
max_output_tokens: number;
is_free: boolean;
discounted: boolean;
discount_pct: number;
saved_pct: number;
pricing: ModelPricing;
}
export interface AdminUser {
id: string;
email: string;
created_at: number;
balance_micro: Micro;
keys: number;
verified: boolean;
role: 'user' | 'admin' | string;
token_limit: number;
tokens_used: number;
token_multiplier: number;
allowed_models_count: number; // 0 = every public model
network_fee_micro: number;
}
export interface AccountLimits {
user_id: string;
balance_micro: Micro;
balance_usd: number;
token_limit: number;
tokens_used: number;
tokens_remaining: number; // -1 = unlimited
token_multiplier: number;
allowed_models: string[];
price_overrides: Record<string, [number, number]>;
network_fee_micro: number;
daily_model_caps: Array<{
model: string;
name: string;
input: { limit: number; used: number; remaining: number };
output: { limit: number; used: number; remaining: number };
resets_at: number;
}>;
}
export interface EmailPrefs {
security: boolean;
usage: boolean;
news: boolean;
promotions: boolean;
}
export interface AccountSettings {
auto_fallback: boolean;
email_prefs: EmailPrefs;
}
export interface AdminModelUsage {
model: string;
days: number;
totals: {
requests: number;
prompt_tokens: number;
completion_tokens: number;
total_tokens: number;
cost_micro: Micro;
cost_usd: number;
accounts: number;
};
per_day: Array<{
day: number;
requests: number;
prompt_tokens: number;
completion_tokens: number;
cost_micro: Micro;
}>;
top_users: Array<{
user_id: string;
email: string;
requests: number;
cost_micro: Micro;
}>;
}
export interface AdminUserLimits {
user_id: string;
email: string;
role: string;
balance_micro: Micro;
balance_usd: number;
token_limit: number;
tokens_used: number;
token_multiplier: number;
allowed_models: string[];
price_overrides: Record<string, [number, number]>;
network_fee_micro: number;
}
export interface UsageResponse {
days: number;
balance_micro: Micro;
balance_usd: number;
totals: {
requests: number;
prompt_tokens: number;
completion_tokens: number;
cost_micro: Micro;
cost_usd: number;
};
per_day: Array<{
day: number;
requests: number;
prompt_tokens: number;
completion_tokens: number;
cost_micro: Micro;
}>;
by_model: Array<{
model: string;
requests: number;
prompt_tokens: number;
completion_tokens: number;
cost_micro: Micro;
}>;
}
export interface Deposit {
id: string;
amount_usd: number;
status: "pending" | "paying" | "completed" | "failed" | "expired" | string;
track_id: string | null;
payment_url: string | null;
created_at: number;
}
export interface Receipt {
receipt_no: string;
amount_usd: number;
paid_at: number;
created_at: number;
track_id: string | null;
url: string;
}
export interface ReceiptDetail {
receipt_no: string;
billed_to: string;
description: string;
amount_usd: number;
currency: "USD";
status: "paid";
paid_at: number;
created_at: number;
issuer: string;
}
export interface NewsItem {
id: string;
title: string;
body: string;
created_at: number;
updated_at: number;
}
export interface StatusSnapshot {
status: "operational" | "degraded" | string;
service: string;
version: string;
time: number;
uptime_seconds: number;
uptime_human: string;
components: Record<string, { status: string }>;
models: { enabled: number; free: number };
news: Array<{ title: string; body: string; created_at: number }>;
}
export interface ChatUsage {
prompt_tokens: number;
completion_tokens: number;
total_tokens: number;
prompt_cache_hit_tokens?: number;
prompt_cache_miss_tokens?: number;
prompt_cache_write_tokens?: number;
cache_read_input_tokens?: number;
cache_creation_input_tokens?: number;
cached_tokens?: number;
completion_thinking_tokens?: number;
completion_tokens_details?: { reasoning_tokens?: number };
cost?: number; // provider-reported, not RelayRouter's charge
}
export interface ChatCompletion {
id: string;
object: "chat.completion";
created: number;
model: string;
choices: Array<{
index: number;
finish_reason: string | null;
message: {
role: "assistant";
content: string | null;
reasoning_content?: string;
tool_calls?: unknown[];
};
}>;
usage: ChatUsage;
}
The project's own copy of these types lives in lib/types.ts and includes a few additional fields used by the UI.