Skip to main content

API Reference

This document provides a complete reference for all Lovrabet OpenAPI interfaces, including SDK usage and underlying HTTP specifications.

Basic Information

Environment URLs

EnvironmentDomain
Productionhttps://runtime.lovrabet.com

Request Specifications

  • Request Method: All interfaces use POST
  • Content Type: application/json
  • Character Encoding: UTF-8
  • Timeout Setting: 30 seconds recommended

Authentication Method

All requests require the following authentication information in HTTP Headers:

Header NameDescriptionExample
X-Time-StampTimestamp (milliseconds)1758903130713
X-App-CodeApplication codeapp-c2dd52a2
X-Dataset-CodeDataset code (required for some APIs)0fefba76fe29...ff
X-TokenSignature TokenjdqqGtzecF2I6FIW...
Using SDK

The SDK automatically adds all required headers without manual intervention.

OpenAPI Interface List

Complete Interface List

Below are all interfaces provided by Lovrabet OpenAPI with detailed information:

Interface NameHTTP MethodFull URL PathSDK MethodDescription
Batch query dataPOST/openapi/data/get-listgetList(params?, sortList?)Paginated query with filtering and sorting
Query single dataPOST/openapi/data/get-onegetOne(id)Get single data detail by ID
Create dataPOST/openapi/data/createcreate(data)Create new data record
Update dataPOST/openapi/data/updateupdate(id, data)Update existing data record
Feature Limitations

OpenAPI currently does not support delete(), getSelectOptions(), and excelExport() operations. For these features, please use Cookie-based WebAPI mode.

Request Parameter Specifications

All OpenAPI request bodies follow this structure:

{
appCode: string; // Application code (required for all interfaces)
datasetCode: string; // Dataset code (required for all data operations)
paramMap: { // Business parameter object
// Specific parameters vary by interface
}
}

Authentication Information Delivery:

  • OpenAPI authentication information is not in the request body, but passed through HTTP Headers:
    • X-Time-Stamp: Timestamp
    • X-App-Code: Application code
    • X-Dataset-Code: Dataset code
    • X-Token: Signature Token
  • SDK automatically handles these headers, developers don't need to add them manually

Interface Parameter Details

1. Batch Query Data (getList)

URL: POST /openapi/data/get-list

Request Body Parameters:

{
appCode: string;
datasetCode: string;
paramMap: {
currentPage?: number; // Current page number, starts from 1
pageSize?: number; // Records per page
ytSortList?: SortList; // Sort configuration (auto-added via SDK sortList parameter)
[key: string]: any; // Other query conditions (based on dataset fields)
}
}

Parameter Description:

Parameter NameTypeRequiredDefaultDescription
appCodestring✅ Yes-Application code
datasetCodestring✅ Yes-Dataset code
paramMap.currentPagenumber❌ No1Current page number, starts from 1
paramMap.pageSizenumber❌ No20Records per page, max 100
paramMap.ytSortListSortList❌ No-Sort configuration array, auto-generated from SDK sortList
paramMap.[fieldName]any❌ No-Other query conditions based on dataset field definitions

Query Condition Examples:

Based on different dataset fields, you can use the following query patterns:

{
// Exact match
status: "active",
customer_type: "vip",

// Fuzzy search (field name with _like suffix)
name_like: "Zhang",

// Range query (field name with _start/_end suffix)
create_time_start: "2024-01-01",
create_time_end: "2024-12-31",
amount_start: 1000,
amount_end: 5000,

// IN query (field name with _in suffix, value as array)
status_in: ["active", "pending"],

// IS NULL query (field name with _is_null suffix)
deleted_at_is_null: true,
}

Sorting Feature (ytSortList):

OpenAPI uses the ytSortList field for sorting, passed through SDK's sortList parameter:

import { SortOrder } from "@lovrabet/sdk";

// SDK usage (recommended)
const result = await client.models.users.filter(
{ currentPage: 1, pageSize: 20 },
[
{ priority: SortOrder.DESC }, // Priority descending
{ createTime: SortOrder.DESC }, // Create time descending
{ name: SortOrder.ASC }, // Name ascending
]
);

// SDK automatically converts sortList to ytSortList field in paramMap
// Actual request body: { appCode, datasetCode, paramMap: { ytSortList: [...] } }
Sorting Notes
  • OpenAPI only supports sorting through ytSortList field
  • When using SDK, pass sort configuration through the second parameter sortList of getList()
  • SDK automatically converts sortList to ytSortList format

Response Data (data field):

{
paging: {
pageSize: number; // Records per page
totalCount: number; // Total record count
currentPage: number; // Current page number
}
tableData: Array<T>; // Data list array
tableColumns: Array<{
title: string; // Column title
dataIndex: string; // Field name
}>;
}

2. Query Single Data (getOne)

URL: POST /openapi/data/get-one

Request Body Parameters:

{
appCode: string;
datasetCode: string;
paramMap: {
id: string | number; // Record ID
}
}

Parameter Description:

Parameter NameTypeRequiredDescription
appCodestring✅ YesApplication code
datasetCodestring✅ YesDataset code
paramMap.idstring/number✅ YesRecord ID to query

Response Data (data field):

{
id: string | number; // Record ID
[key: string]: any; // Other fields based on dataset definition
}

3. Create Data (create)

URL: POST /openapi/data/create

Request Body Parameters:

{
appCode: string;
datasetCode: string;
paramMap: {
[key: string]: any; // Data fields to create
}
}

Parameter Description:

Parameter NameTypeRequiredDescription
appCodestring✅ YesApplication code
datasetCodestring✅ YesDataset code
paramMap.[fieldName]anyBased on field definitionData to create, fields and requirements based on dataset definition

Notes:

  • System fields (such as id, gmt_create, gmt_modified) are auto-generated, no need to provide
  • Required fields must be provided, otherwise parameter error will be returned
  • Field types must match dataset definition

Response Data (data field):

{
id: string | number; // ID of newly created record
[key: string]: any; // Complete record data (including auto-generated fields)
}

4. Update Data (update)

URL: POST /openapi/data/update

Request Body Parameters:

{
appCode: string;
datasetCode: string;
paramMap: {
id: string | number; // Record ID to update
[key: string]: any; // Fields to update
}
}

Parameter Description:

Parameter NameTypeRequiredDescription
appCodestring✅ YesApplication code
datasetCodestring✅ YesDataset code
paramMap.idstring/number✅ YesRecord ID to update
paramMap.[fieldName]any❌ NoFields to update, only need to provide fields to modify (partial update)

Notes:

  • Supports partial updates, only need to provide fields to modify
  • gmt_modified field is automatically updated
  • Cannot modify id and gmt_create fields

Response Data (data field):

{
id: string | number; // Record ID
[key: string]: any; // Complete updated record data
}

Response Structure

Common Response Format

All interface responses contain the following top-level fields (returned by platform gateway):

{
success: boolean; // Whether request succeeded
msg: string; // Response message
data: any; // Response data
errorCode?: number; // Error code (returned on failure)
errorMsg?: string; // Error message (returned on failure)
}

getList Response Fixed Fields

The data field of getList interface contains the following three fixed fields (SDK return structure is consistent with platform):

{
paging: {
// 【Fixed field】Pagination information
pageSize: number; // Records per page
totalCount: number; // Total record count
currentPage: number; // Current page number
}
tableData: Array<T>; // 【Fixed field】Data list array
tableColumns: Array<{
// 【Fixed field】Table column definition
title: string; // Column title
dataIndex: string; // Field name
}>;
}

SDK Usage

Create Client

import { createClient } from "@lovrabet/sdk";

const client = createClient({
appCode: "your-app-code",
accessKey: process.env.LOVRABET_ACCESS_KEY,
models: {
users: {
tableName: "users",
datasetCode: "your-dataset-code",
},
},
});

SDK Method List

Each model instance provides the following methods:

MethodDescriptionCorresponding API
getList(params?)Batch query data/openapi/data/get-list
getOne(id)Query single data/openapi/data/get-one
create(data)Create single data/openapi/data/create
update(id, data)Update single data/openapi/data/update

Detailed API Description

1. Batch Query Data (getList)

Paginated query of data in dataset, supports filtering, sorting, etc.

SDK Usage

Basic Query:

const response = await client.models.users.filter({
currentPage: 1,
pageSize: 20,
});

// Destructure response
const { paging, tableData, tableColumns } = response;

console.log("Total count:", paging.totalCount);
console.log("Current page:", paging.currentPage);
console.log("Data:", tableData);
console.log("Column definitions:", tableColumns);

Conditional Query:

const response = await client.models.users.filter({
currentPage: 1,
pageSize: 20,
// Query conditions (based on actual dataset fields)
status: "active",
customer_type: "vip",
});

Paginated Iteration:

async function getAllUsers() {
const allUsers = [];
let currentPage = 1;
const pageSize = 50;

while (true) {
const { paging, tableData } = await client.models.users.filter({
currentPage,
pageSize,
});

allUsers.push(...tableData);

// Check if there's more data
if (currentPage * pageSize >= paging.totalCount) {
break;
}

currentPage++;

// Avoid request flooding
await new Promise((resolve) => setTimeout(resolve, 100));
}

return allUsers;
}

HTTP Specifications

Interface URL: POST /openapi/data/get-list

Request Headers:

X-Time-Stamp: {timestamp}
X-App-Code: {appCode}
X-Dataset-Code: {datasetCode}
X-Token: {token}

Request Body:

{
"appCode": "app-c2dd52a2",
"datasetCode": "0fefba76fe29440194841f4825df53ff",
"paramMap": {
"pageSize": 10,
"currentPage": 1,
"status": "active",
"customer_type": "vip",
"create_time_start": "2024-01-01",
"create_time_end": "2024-12-31"
}
}

Request Body with Sorting Example:

{
"appCode": "app-c2dd52a2",
"datasetCode": "0fefba76fe29440194841f4825df53ff",
"paramMap": {
"pageSize": 10,
"currentPage": 1,
"ytSortList": [{ "gmt_create": "desc" }, { "id": "asc" }],
"status": "active"
}
}

Response Structure Description:

The data field contains three fixed fields:

  • paging - Pagination information (fixed field)
  • tableData - Data list (fixed field)
  • tableColumns - Table column definition (fixed field)

Response Example:

{
"success": true,
"msg": "Query successful",
"data": {
"paging": {
"pageSize": 10,
"totalCount": 156,
"currentPage": 1
},
"tableData": [
{
"id": "123",
"customer_name": "Example Customer",
"customer_type": "vip",
"contact_person": "Zhang San",
"phone": "13800138000",
"email": "example@example.com",
"address": "Chaoyang District, Beijing",
"status": "active",
"credit_level": "A",
"gmt_create": "2024-01-15 10:30:00",
"gmt_modified": "2024-03-20 14:25:00"
}
],
"tableColumns": [
{
"title": "Customer Name",
"dataIndex": "customer_name"
},
{
"title": "Customer Type",
"dataIndex": "customer_type"
},
{
"title": "Contact Person",
"dataIndex": "contact_person"
}
]
}
}

Query Parameter Details

Pagination Parameters:

ParameterTypeRequiredDefaultDescription
pageSizenumberNo10Records per page, max 100
currentPagenumberNo1Current page, starts from 1

Sorting Parameters:

ParameterTypeRequiredDescription
ytSortListArrayNoSort configuration array, format: [{ "fieldName": "asc/desc" }]
Sorting Usage

When using SDK, pass sort configuration through the second parameter sortList of getList(), SDK automatically converts to ytSortList field. See "Sorting Feature" section above for details.

Conditional Query:

Query parameters vary by dataset fields, common query methods:

{
// Exact match
field_name: "value",

// Fuzzy search (some fields support)
field_name_like: "value",

// Range query
field_name_start: "value1",
field_name_end: "value2",

// IN query (some fields support)
field_name_in: ["value1", "value2"],

// NULL check (some fields support)
field_name_is_null: true,
}

2. Query Single Data (getOne)

Query single detailed data by unique identifier.

SDK Usage

// Query single data
const user = await client.models.users.getOne("user-id");

console.log(user);
// Returns single object containing all fields of the record

// Or use object parameter
const user = await client.models.users.getOne({
id: 14,
});

HTTP Specifications

Interface URL: POST /openapi/data/get-one

Request Headers:

X-Time-Stamp: {timestamp}
X-App-Code: {appCode}
X-Dataset-Code: {datasetCode}
X-Token: {token}

Request Body:

{
"appCode": "app-c2dd52a2",
"datasetCode": "0fefba76fe29440194841f4825df53ff",
"paramMap": {
"id": 14
}
}

Response Example:

{
"success": true,
"msg": "Query successful",
"data": {
"id": 14,
"customer_name": "Example Customer",
"customer_type": "vip",
"contact_person": "Zhang San",
"phone": "13800138000",
"email": "example@example.com",
"address": "XX Road XX, Chaoyang District, Beijing",
"status": "active",
"credit_level": "A",
"credit_amount": 100000.0,
"used_amount": 35000.0,
"available_amount": 65000.0,
"contract_start": "2024-01-01",
"contract_end": "2024-12-31",
"sales_person": "Manager Wang",
"department": "North China Sales Department",
"gmt_create": "2024-01-15 10:30:00",
"gmt_modified": "2024-03-20 14:25:00",
"remark": "Important VIP customer, requires priority maintenance"
}
}

3. Create Single Data (create)

Create a new data record.

SDK Usage

// Create customer information
const newCustomer = await client.models.users.create({
customer_name: "New Customer Company",
customer_type: "enterprise",
contact_person: "Manager Li",
phone: "13900139000",
email: "contact@newcustomer.com",
address: "Pudong New Area, Shanghai",
status: "active",
credit_level: "B",
});

console.log("New customer ID:", newCustomer.id);
console.log("Created time:", newCustomer.gmt_create);

HTTP Specifications

Interface URL: POST /openapi/data/create

Request Headers:

X-Time-Stamp: {timestamp}
X-App-Code: {appCode}
X-Dataset-Code: {datasetCode}
X-Token: {token}

Request Body:

{
"appCode": "app-c2dd52a2",
"datasetCode": "0fefba76fe29440194841f4825df53ff",
"paramMap": {
"customer_name": "New Customer Company",
"customer_type": "enterprise",
"contact_person": "Manager Li",
"phone": "13900139000",
"email": "contact@newcustomer.com",
"address": "Pudong New Area, Shanghai",
"status": "active",
"credit_level": "B"
}
}

Response Example:

{
"success": true,
"msg": "Created successfully",
"data": {
"id": 158,
"customer_name": "New Customer Company",
"customer_type": "enterprise",
"contact_person": "Manager Li",
"phone": "13900139000",
"email": "contact@newcustomer.com",
"address": "Pudong New Area, Shanghai",
"status": "active",
"credit_level": "B",
"credit_amount": 0.0,
"used_amount": 0.0,
"available_amount": 0.0,
"gmt_create": "2025-10-10 15:30:00",
"gmt_modified": "2025-10-10 15:30:00"
}
}

4. Update Single Data (update)

Update partial or all fields of an existing data record by ID.

SDK Usage

// Update customer information
const updatedCustomer = await client.models.users.update(158, {
customer_type: "vip",
credit_level: "A",
credit_amount: 200000.0,
remark: "Upgraded to VIP customer, increased credit limit",
});

console.log("Updated customer type:", updatedCustomer.customer_type);
console.log("Update time:", updatedCustomer.gmt_modified);

Batch Update Example:

// Batch update multiple customer statuses
const customerIds = [101, 102, 103];

const updateResults = await Promise.all(
customerIds.map((id) =>
client.models.users.update(id, {
status: "inactive",
remark: "Batch deactivation",
})
)
);

console.log(`Successfully updated ${updateResults.length} customers`);

HTTP Specifications

Interface URL: POST /openapi/data/update

Request Headers:

X-Time-Stamp: {timestamp}
X-App-Code: {appCode}
X-Dataset-Code: {datasetCode}
X-Token: {token}

Request Body:

{
"appCode": "app-c2dd52a2",
"datasetCode": "0fefba76fe29440194841f4825df53ff",
"paramMap": {
"id": 158,
"customer_type": "vip",
"credit_level": "A",
"credit_amount": 200000.0,
"remark": "Upgraded to VIP customer, increased credit limit"
}
}

Response Example:

{
"success": true,
"msg": "Updated successfully",
"data": {
"id": 158,
"customer_name": "New Customer Company",
"customer_type": "vip",
"contact_person": "Manager Li",
"phone": "13900139000",
"email": "contact@newcustomer.com",
"address": "Pudong New Area, Shanghai",
"status": "active",
"credit_level": "A",
"credit_amount": 200000.0,
"used_amount": 0.0,
"available_amount": 200000.0,
"gmt_create": "2025-10-10 15:30:00",
"gmt_modified": "2025-10-10 16:45:00",
"remark": "Upgraded to VIP customer, increased credit limit"
}
}
Soft Delete Recommendation

OpenAPI currently does not provide physical deletion interface. If you need to delete data, it's recommended to use "soft delete" approach by updating a status field via update() method:

// Recommended: Use soft delete (update status to deleted)
await client.models.users.update(158, {
status: "deleted",
deleted_at: new Date().toISOString(),
remark: "Deleted per customer request",
});

console.log("Customer marked as deleted");

Advantages of soft delete:

  • ✅ Data is recoverable
  • ✅ Maintains operation records
  • ✅ Complies with data compliance requirements

Error Handling

Error Code Description

When a request fails, the success field is false, and corresponding error code and message are returned.

Error CodeDescriptionSolution
1001Parameter errorCheck if request parameters are complete and formatted correctly
1002Signature verification failedCheck Access Key, signature algorithm, timestamp
1003Timestamp expiredToken expired (10 minutes), regenerate
1004Application not foundCheck if App Code is correct
1005Dataset not foundCheck if Dataset Code is correct
1006No access permissionConfirm if application has access to dataset
2001Query timeoutOptimize query conditions, reduce data volume
2002Data not foundCheck if query conditions or ID is correct
3001Internal server errorContact technical support
4001Request rate exceededReduce request frequency, implement rate limiting

Error Response Example

{
"success": false,
"msg": null,
"data": null,
"errorCode": 1002,
"errorMsg": "Signature verification failed, please check Token generation algorithm"
}

SDK Error Handling

import { LovrabetError } from "@lovrabet/sdk";

try {
const users = await client.models.users.filter();
} catch (error) {
if (error instanceof LovrabetError) {
console.error("Error code:", error.statusCode);
console.error("Error message:", error.message);
console.error("Error details:", error.details);

// Handle based on error code
switch (error.statusCode) {
case 1002:
console.error("Signature verification failed, check Access Key");
break;
case 1003:
console.error("Token expired, need to refresh");
break;
case 1006:
console.error("No permission to access this dataset");
break;
default:
console.error("Other error");
}
} else {
console.error("Unknown error:", error);
}
}

Advanced Usage

1. TypeScript Type Support

import { createClient, ListResponse } from "@lovrabet/sdk";

// Define data type
interface User {
id: string;
name: string;
email: string;
status: "active" | "inactive";
gmt_create: string;
}

const client = createClient({
// ... configuration
});

// Typed query
const response: ListResponse<User> = await client.models.users.filter();

response.tableData.forEach((user: User) => {
console.log(user.name, user.email);
});

2. Multi-Model Configuration

const client = createClient({
appCode: "your-app-code",
accessKey: process.env.LOVRABET_ACCESS_KEY,
models: {
users: {
tableName: "users",
datasetCode: "dataset-001",
},
orders: {
tableName: "orders",
datasetCode: "dataset-002",
},
products: {
tableName: "products",
datasetCode: "dataset-003",
},
},
});

// Use different models
const users = await client.models.users.filter();
const orders = await client.models.orders.filter();
const products = await client.models.products.filter();

3. Response Data Transformation

const response = await client.models.users.filter();

// Extract pure data array
const users = response.tableData;

// Extract column definitions (for dynamic table UI construction)
const columns = response.tableColumns.map((col) => ({
title: col.title,
field: col.dataIndex,
}));

// Pagination information
const { totalCount, currentPage, pageSize } = response.paging;
const totalPages = Math.ceil(totalCount / pageSize);

4. Request Interception and Logging

import { createClient } from "@lovrabet/sdk";

const client = createClient({
appCode: "your-app-code",
accessKey: process.env.LOVRABET_ACCESS_KEY,
models: {
/* ... */
},
});

// Wrap request method to add logging
const originalGetList = client.models.users.getList.bind(client.models.users);

client.models.users.getList = async function (params) {
console.log("Request parameters:", params);
const startTime = Date.now();

try {
const result = await originalGetList(params);
console.log("Request successful, time:", Date.now() - startTime, "ms");
return result;
} catch (error) {
console.error("Request failed:", error);
throw error;
}
};

Performance Optimization

1. Pagination Query Recommendations

// ✅ Recommended: Reasonable page size
const response = await client.models.users.filter({
pageSize: 20, // 10-50 records is appropriate
});

// ❌ Avoid: Querying too much data at once
const response = await client.models.users.filter({
pageSize: 1000, // Not recommended, affects performance
});

2. Avoid N+1 Queries

// ❌ Not recommended: Loop calling getOne
for (const id of userIds) {
const user = await client.models.users.getOne(id);
// Process user
}

// ✅ Recommended: Use getList for batch query
const users = await client.models.users.filter({
id_in: userIds, // Assuming IN query is supported
});

3. Implement Caching

class CachedApiClient {
private cache = new Map<string, { data: any; timestamp: number }>();
private cacheTTL = 60000; // 1 minute

async getListCached(params: any) {
const cacheKey = JSON.stringify(params);
const cached = this.cache.get(cacheKey);

if (cached && Date.now() - cached.timestamp < this.cacheTTL) {
return cached.data;
}

const data = await client.models.users.filter(params);
this.cache.set(cacheKey, { data, timestamp: Date.now() });

return data;
}
}

4. Concurrency Control

// Limit concurrency
async function batchQuery(ids: string[], concurrency = 3) {
const results = [];

for (let i = 0; i < ids.length; i += concurrency) {
const batch = ids.slice(i, i + concurrency);
const batchResults = await Promise.all(
batch.map((id) => client.models.users.getOne(id))
);
results.push(...batchResults);
}

return results;
}

Request Limits

Rate Limits

Limit TypeLimit Value
Per minute600 requests
Per hour10,000 requests
Per day100,000 requests

Data Volume Limits

Limit TypeLimit Value
Max records per single query100 records
Max response body size10MB
Max request body size1MB

Concurrency Limits

Limit TypeLimit Value
Max concurrent connections per app10
Performance Recommendations
  • Use connection pools to manage requests
  • Implement request queues and rate limiting mechanisms
  • Set reasonable timeout values

Raw HTTP Requests (Advanced)

For Reference Only

Using SDK is recommended. The following content is for developers who need low-level implementation.

Signature Generation

import crypto from "crypto";

function generateToken(
timestamp: number,
appCode: string,
datasetCode: string,
accessKey: string,
secretKey: string = "lovrabet"
): string {
const params: Record<string, string> = {
accessKey: accessKey,
timeStamp: timestamp.toString(),
appCode: appCode,
};

if (datasetCode) {
params.datasetCode = datasetCode;
}

// Sort parameters by dictionary order
const sortedParams = Object.keys(params)
.sort()
.map((key) => `${key}=${params[key]}`)
.join("&");

// Calculate HMAC-SHA256
return crypto
.createHmac("sha256", secretKey)
.update(sortedParams, "utf8")
.digest("base64");
}

HTTP Request Example

async function getListRaw() {
const timestamp = Date.now();
const appCode = "app-c2dd52a2";
const datasetCode = "0fefba76fe29440194841f4825df53ff";
const accessKey = "your-access-key";

const token = generateToken(timestamp, appCode, datasetCode, accessKey);

const response = await fetch(
"https://runtime.lovrabet.com/openapi/data/get-list",
{
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Time-Stamp": timestamp.toString(),
"X-App-Code": appCode,
"X-Dataset-Code": datasetCode,
"X-Token": token,
},
body: JSON.stringify({
appCode: appCode,
datasetCode: datasetCode,
paramMap: {
pageSize: 10,
currentPage: 1,
},
}),
}
);

return await response.json();
}

Best Practices

1. Error Handling and Retry

async function apiCallWithRetry(
fn: () => Promise<any>,
maxRetries = 3,
delay = 1000
) {
for (let i = 0; i < maxRetries; i++) {
try {
return await fn();
} catch (error) {
if (error instanceof LovrabetError) {
// Token expiration can be retried
if (error.statusCode === 1003 && i < maxRetries - 1) {
await new Promise((resolve) => setTimeout(resolve, delay));
continue;
}
}
throw error;
}
}
}

// Usage
const users = await apiCallWithRetry(() => client.models.users.filter());

2. Logging

function logApiCall(
method: string,
params: any,
result: any,
duration: number
) {
console.log({
timestamp: new Date().toISOString(),
method: method,
params: params,
success: true,
duration: duration,
recordCount: result.tableData?.length || 0,
});
}

3. Monitoring and Alerting

class ApiMonitor {
private errorCount = 0;
private errorThreshold = 10;

async callWithMonitoring(fn: () => Promise<any>) {
try {
const result = await fn();
this.errorCount = 0; // Reset error count
return result;
} catch (error) {
this.errorCount++;

if (this.errorCount >= this.errorThreshold) {
// Trigger alert
this.sendAlert("API error rate too high");
}

throw error;
}
}

private sendAlert(message: string) {
// Send alert notification
console.error("Alert:", message);
}
}

Need Help?

If you encounter issues:

  1. Check error code descriptions in this document
  2. Check GitHub Issues
  3. Contact your business manager for technical support