This skill provides a complete guide to building pages, retrieving data in real time, and manipulating data using the Mingdao Cloud HAP V3 API.
Overview
Mingdao Cloud HAP (High-performance Application Platform) is a super application platform, and many applications can be built on this foundation. Through the HAP V3 API, you can:
- In a custom view pluginCall the V3 API to manipulate data
- In a standalone frontend pageUse the V3 API to orchestrate business logic
- Retrieve and manipulate in real timeData in Mingdao Cloud applications
Core capabilities:
- ✅ Complete API usage workflow (from building an application from scratch to data manipulation)
- ✅ Detailed field type handling specifications
- ✅ Complete Filter syntax
- ✅ In-depth query guide for related fields
- ✅ Common pitfalls and solutions
- ✅ Performance optimization best practices
Detailed documentation: Refer to references/hap-api-usage-guide.md for the complete API usage specifications
Quick Start
1. Obtain API credentials
Method 1: Extract from MCP configuration (recommended)
If the user has already configured the HAP application execution MCP, the AI assistant shouldautomatically extract the authentication key from the MCP configuration, rather than asking the user to enter it manually.
Automated extraction steps
-
Read the configured HAP MCP configuration file(based on the editor/client's MCP configuration, for example its global
settings.json)- macOS:
~/Library/Application Support/<编辑器>/User/settings.json - Windows:
%APPDATA%\<编辑器>\User\settings.json - Linux:
~/.config/<编辑器>/User/settings.json
- macOS:
-
Find the MCP configuration
- In the
mcpServersobject, find the HAP MCP server configuration (urlpoints toapi.mingdao.com/mcporapi2.mingdao.com/mcp) - Common naming: AppKey authentication is mostly
hap-mcp-应用名; personal authentication is mostlyhap_personal_mcp
- In the
-
Identify the authentication type and parse the parameters
HAP MCP configuration has two authentication formats, which need to be handled separately:
Format 1 · AppKey + Sign(the key is written in the
urlquery parameters){ "mcpServers": { "hap-mcp-应用名": { "url": "https://api2.mingdao.com/mcp?HAP-Appkey=你的Appkey&HAP-Sign=你的Sign" } } }Format 2 · PAT / OAuth(the token is written in the
headers.Authorization){ "mcpServers": { "hap_personal_mcp": { "url": "https://api2.mingdao.com/mcp", "headers": { "Authorization": "Bearer pat_XXX" } } } } -
Extract authentication information
- Format 1: From the
urlquery parameters, takeHAP-Appkey、HAP-Sign(the parameters may be URL-encoded and need to be correctly decoded), and put them into the request headers with the same names when making the request. - Format 2: From
headers.Authorization, take the entire stringBearer …, and put it as-is into theAuthorizationheader when making the request; if the API requires it, also includeHAP-Appid(application ID). - Determination rule:
urlcontainsHAP-Appkey→ use Format 1; otherwise checkheaders.Authorization→ use Format 2.
- Format 1: From the
Code example (AI assistant operation)
// 1. 读取已配置的 HAP MCP 配置文件(路径取决于所用编辑器/客户端,下方以其全局 settings.json 为例)
const editorDir = 'YourEditor'; // 替换为实际编辑器/客户端目录名
const settingsPath = process.platform === 'darwin'
? `${process.env.HOME}/Library/Application Support/${editorDir}/User/settings.json`
: process.platform === 'win32'
? `${process.env.APPDATA}/${editorDir}/User/settings.json`
: `${process.env.HOME}/.config/${editorDir}/User/settings.json`;
const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
// 2. 查找 HAP MCP 配置(url 指向 api.mingdao.com/mcp 或 api2.mingdao.com/mcp)
const mcpServers = settings.mcpServers || {};
const hapMcpConfig = Object.entries(mcpServers).find(
([name, config]) => config.url && /api2?\.mingdao\.com\/mcp/.test(config.url)
);
if (hapMcpConfig) {
const [, config] = hapMcpConfig;
const url = new URL(config.url);
// 3. 识别鉴权类型并提取
let auth;
if (url.searchParams.get('HAP-Appkey')) {
// 格式一:AppKey + Sign
auth = {
type: 'appkey',
headers: {
'HAP-Appkey': url.searchParams.get('HAP-Appkey'),
'HAP-Sign': url.searchParams.get('HAP-Sign'),
},
};
} else if (config.headers?.Authorization) {
// 格式二:PAT / OAuth(Bearer Token)
auth = {
type: 'bearer',
headers: {
'Authorization': config.headers.Authorization, // 原样使用 "Bearer ..."
// 'HAP-Appid': '应用ID', // 应用级接口必填,按需补充
},
};
}
// 4. 将 auth.headers 合并进 API 请求头即可
console.log(auth);
}
Actual operation process
When the user needs to call the HAP API, the AI should:
-
Check whether MCP is already configured
- Read the configured HAP MCP configuration
- Find the
hap-mcp-*configuration
-
Extract authentication information
- After finding the configuration, automatically extract according to the format: the
HAP-Appkey/HAP-Signin the URL parameters, or theheaders.Authorizationin theBearertoken - If multiple MCP configurations are found, ask the user which application to use
- After finding the configuration, automatically extract according to the format: the
-
Use the extracted authentication
- Include the extracted authentication header in the API request headers (
HAP-Appkey+HAP-Sign, orAuthorization: Bearer …, addHAP-Appid) - If extraction fails, prompt the user to provide it manually or check the MCP configuration
- Include the extracted authentication header in the API request headers (
Notes
- ✅ Prefer using the MCP configuration: If the user has already configured MCP, prefer extracting from the configuration
- ✅ URL decoding: Note that URL parameters may be encoded and need to be decoded correctly
- ✅ Multiple applications: If multiple HAP MCPs are configured, ask the user which application to use
- ⚠️ Configuration does not exist: If no MCP configuration is found, prompt the user to configure MCP first or provide the key manually
- ⚠️ Permission issues: If the configuration file cannot be read, prompt the user to check file permissions
Method 2: Manual retrieval
If the user has not configured MCP or needs to provide it manually:
- Log in to Mingdao Cloud → Application → Settings → API Key
- Copy the Appkey and Sign
- Or provide the MCP configuration information and let the AI extract it automatically
2. Configure request headers (authentication)
Authentication is used to verify "who you are and whether you have permission". Credentials are uniformly placed in the request Header and must be carried with every request. V3 supports three authentication methods:
| Method | Header parameter | Operating identity | Validity period | Applicable scenarios |
|---|---|---|---|---|
| AppKey + Sign | HAP-Appkey、HAP-Sign |
Application administrator | Long-term | Server-side integration |
| PAT | Authorization: Bearer {access_token}、HAP-Appid(required for some APIs) |
Personal | Configurable | Personal scripts / tools |
| OAuth 2.0 | Authorization: Bearer {access_token}、HAP-Appid(required for some APIs) |
Authorized user | Short-term, automatically refreshed | Third-party application integration |
Method 1: AppKey + Sign (application key, most commonly used)
Created by an administrator, accesses data as an application administrator.
const headers = {
'Content-Type': 'application/json',
'HAP-Appkey': '你的Appkey',
'HAP-Sign': '你的Sign'
};
⚠️ The request header names are
HAP-AppkeyandHAP-Sign(notAppKeyandSign)。
Method 2: PAT (Personal Access Token)
Created by yourself, operates as an individual, and allows you to set the validity period and permission scope.
const headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer 你的access_token',
'HAP-Appid': '应用ID' // 应用级接口必填
};
Method 3: OAuth 2.0 (third-party authorization)
The user completes authorization through OAuth integration; it is short-term valid and supports automatic refresh. The request header is the same as PAT:
const headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer 你的access_token',
'HAP-Appid': '应用ID' // 应用级接口必填
};
Additional parameters for PAT / OAuth 2.0:
HAP-Appid(Header): Identifies the source application; the value is the application ID,required for application-level APIs。orgId(Query): Identifies the source organization; the value is the organization ID,required for organization-level APIs(such as getting the application list, creating an application).
Choose among three methods based on the scenario: use AppKey + Sign for server-side integration; use PAT for personal scripts/tools; use OAuth 2.0 for third-party application integration.
3. Get API Documentation
Using Apifox MCP Server (recommended):
{
"应用 API - API 文档": {
"command": "npx",
"args": [
"-y",
"apifox-mcp-server@latest",
"--site-id=5442569"
]
}
}
Online documentation resources:
Core Workflow
Phase 1: Preparation
Step 1: Get API Credentials
- Preferred method: Automatically extract Appkey and Sign from the configured HAP MCP configuration (if the user has configured it)
- Alternative method: Manually obtain from the HAP backend or have the user provide them
Step 2: Configure API Request Headers
- Set the request headers using the extracted or provided Appkey and Sign
- Set the
HAP-AppkeyandHAP-Signrequest headers
Phase 2: Create Application Structure
Step 3: Get Application Information (optional)
GET /v3/app/info
Step 4: Create Worksheet
POST /v3/app/worksheets
{
"name": "客户信息表",
"alias": "customers",
"fields": [
{
"name": "客户名称",
"alias": "customer_name",
"type": "Text",
"isTitle": true,
"required": true
}
]
}
Detailed specification: Refer to references/hap-api-usage-guide.md Section 1
Phase 3: Populate Data
Step 5: Prepare Option Field Mapping
- For single-select/multi-select fields, you need to first obtain the option key (UUID)
- Query the worksheet structure to get the options list
Step 6: Create Records
POST /v3/app/worksheets/{worksheet_id}/rows
{
"fields": [
{
"id": "customer_name",
"value": "明道云科技有限公司"
},
{
"id": "customer_type",
"value": ["74c7b607-864d-4cc4-b401-28acba2636e9"] // ⚠️ 使用选项key
}
],
"triggerWorkflow": true
}
Key points:
- ⚠️ Option fields must use the key, not the display text
- ⚠️ Option fields must use array format even for single-select
- ✅ Numeric fields are passed as numbers when writing, and returned as strings when reading
Detailed specification: Refer to references/hap-api-usage-guide.md Section 3
Phase 4: Query and Analyze Data
Step 7: Query Record List
POST /v3/app/worksheets/{worksheet_id}/rows/list
{
"filter": {
"type": "group",
"logic": "AND",
"children": [
{
"type": "condition",
"field": "customer_type",
"operator": "eq",
"value": ["74c7b607-864d-4cc4-b401-28acba2636e9"] // 使用key
}
]
},
"sorts": [{
"field": "annual_budget",
"isAsc": false
}],
"pageIndex": 1,
"pageSize": 20
}
Detailed specification: Refer to references/hap-api-usage-guide.md Section 4
Filter Specification ⭐Key Point
Filter Object Structure
Basic structure:
Filter = {
type: 'group' | 'condition';
// type='group' 时的字段
logic?: 'AND' | 'OR';
children?: Filter[]; // 子条件,最多两层嵌套
// type='condition' 时的字段
field?: string; // 字段ID或别名
operator?: string; // 操作符
value?: any[]; // 值数组
}
Rules:
- The top level must be of
grouptype - At most two levels of nesting: group → group → condition
- The children of the same group must be of the same type
- group must specify
logic(AND/OR) - condition must specify
field,operator
Complete List of Operators
| Operator | Description | Requires value | value format | Applicable fields |
|---|---|---|---|---|
eq |
Equals | ✅ | ["值"] |
All types |
ne |
Not equals | ✅ | ["值"] |
All types |
contains |
Contains | ✅ | ["值"] |
Text, MultipleSelect |
notcontains |
Does not contain | ✅ | ["值"] |
Text, MultipleSelect |
startswith |
Starts with | ✅ | ["值"] |
Text |
endswith |
Ends with | ✅ | ["值"] |
Text |
gt |
Greater than | ✅ | ["值"] |
Number, Date |
gte |
Greater than or equal to | ✅ | ["值"] |
Number, Date |
lt |
Less than | ✅ | ["值"] |
Number, Date |
lte |
Less than or equal to | ✅ | ["值"] |
Number, Date |
between |
Between | ✅ | ["最小值", "最大值"] |
Number, Date |
isempty |
Is empty | ❌ | Not required | All types |
isnotempty |
Is not empty | ❌ | Not required | All types |
notin |
Not in | ✅ | ["ID1", "ID2"] |
Multi-value exclusion for multi-select/member/department/relation, etc. |
in |
In... | ✅ | ["值1", "值2"] |
All types (Relation uses rowid array) |
concurrent |
Also includes | ✅ | ["值1", "值2"] |
MultipleSelect |
Filter examples
Example 1: Single-select field filter (⚠️ must use key)
{
"type": "group",
"logic": "AND",
"children": [{
"type": "condition",
"field": "customer_type",
"operator": "eq",
"value": ["74c7b607-864d-4cc4-b401-28acba2636e9"] // ✅ 使用key
}]
}
// ❌ 错误: value: ["成交客户"] // 不能用显示文本!
Example 2: Numeric range filter (⚠️ value must be a string array)
{
"type": "condition",
"field": "annual_budget",
"operator": "between",
"value": ["500000", "2000000"] // ✅ 字符串数组
}
// ❌ 错误: value: [500000, 2000000] // 不能用数字!
Example 3: Relation field filter (⚠️ use in or eq)
{
"type": "condition",
"field": "related_customer",
"operator": "in", // ✅ 关联字段用 in(多值)或 eq(单值)
"value": ["customer-row-id"] // 传入关联记录的 rowid 数组
}
// ❌ 错误: operator: "belongsto" // V3 API 无 belongsto 运算符,关联字段应用 in/eq + rowid
Detailed specification: Reference references/hap-api-usage-guide.md Section 4
Field type handling specification
Field type / Code / filter operator comparison table (API authoritative)⭐
This is field Code and each field's supported filter operators authoritative basis. Key points:
- V3 API does not have the
belongstooperator——fields such as Department and Relation all use the operators in this table (e.g.in、eq、notin)。-indicates the capability is not supported; filter syntax can only use values from the "supported filter operators" column for the corresponding field.
| Type | Code | Description | API create | API query | Supported filter operators |
|---|---|---|---|---|---|
| Text | 2 | Text | ✓ | ✓ | eq, ne, contains, concurrent, notcontains, startswith, notstartswith, endswith, notendswith, isempty, isnotempty |
| PhoneNumber | 3 | Mobile phone | - | ✓ | Same as Text |
| LandlinePhone | 4 | Landline | - | ✓ | Same as Text |
| 5 | - | ✓ | Same as Text |
||
| Number | 6 | Number | ✓ | ✓ | eq, ne, gt, lt, ge, le, between, notbetween, isempty, isnotempty |
| Certificate | 7 | ID document | - | ✓ | Same as Text |
| Currency | 8 | Amount | - | ✓ | Same as Number |
| SingleSelect | 9 | Single select | ✓ | ✓ | eq, ne, in, notin, isempty, isnotempty |
| MultipleSelect | 10 | Multiple select | ✓ | ✓ | eq, ne, in, notin, concurrent, isempty, isnotempty |
| Dropdown | 11 | Dropdown | - | ✓ | eq, ne, in, notin, isempty, isnotempty |
| Attachment | 14 | Attachment | ✓ | ✓ | isempty, isnotempty |
| Date | 15 | Date | ✓ | ✓ | between, notbetween |
| DateTime | 16 | Time | ✓ | ✓ | between, notbetween |
| Region | 19/23/24 | Region | - | ✓ | eq, ne, between, notbetween, in, isempty, isnotempty |
| DynamicLink | 21 | Free link | - | ✓ | isempty, isnotempty |
| Divider | 22 | Segment | - | - | - |
| AmountInWords | 25 | Amount in words | - | ✓ | Same as Number |
| Collaborator | 26 | Member | ✓ | ✓ | eq, ne, in, notin, concurrent, isempty, isnotempty |
| Department | 27 | Department | - | ✓ | eq, ne, between, notbetween, in, notin, concurrent, isempty, isnotempty |
| Rating | 28 | Rating | - | ✓ | Same as Number |
| Relation | 29 | Related record | ✓ | ✓ | eq, ne, in, notin, concurrent, isempty, isnotempty |
| Lookup | 30 | Lookup field | - | ✓ | - |
| Formula | 31 | Formula | - | ✓ | Same as Number |
| Concatenate | 32 | Text concatenation | - | ✓ | Same as Text |
| AutoNumber | 33 | Auto number | - | ✓ | Same as Text |
| SubTable | 34 | Subtable | - | ✓ | isempty, isnotempty |
| CascadingSelect | 35 | Cascading select | - | ✓ | eq, ne, between, notbetween, isempty, isnotempty |
| Checkbox | 36 | Checkbox | - | ✓ | isempty, isnotempty |
| Rollup | 37 | Rollup | - | ✓ | Same as Number |
| DateFormula | 38 | Formula (Date) | - | ✓ | - |
| CodeScan | 39 | Scan code | - | ✓ | - |
| Location | 40 | Location | - | ✓ | isempty, isnotempty |
| RichText | 41 | Rich text | - | ✓ | isempty, isnotempty |
| Signature | 42 | Signature | - | ✓ | isempty, isnotempty |
| OCR | 43 | Text recognition | - | ✓ | - |
| Role | 44 | Role | - | ✓ | - |
| Embed | 45 | Embed | - | - | - |
| Time | 46 | Time | ✓ | ✓ | between, notbetween |
| Barcode | 47 | Barcode | - | ✓ | - |
| OrgRole | 48 | Organization role | - | ✓ | eq, ne, in, notin, concurrent, isempty, isnotempty |
| Button | 49 | API query (button) | - | - | - |
| APIQuery | 50 | API query (dropdown) | - | - | - |
| QueryRecord | 51 | Query record | - | - | - |
| Section | 52 | Tab | - | - | - |
| FunctionFormula | 53 | Function formula | - | ✓ | - |
| CustomField | 54 | Custom field | - | - | - |
| Array | 10000003 | Array (workflow) | - | - | - |
| Object | 10000006 | Object (workflow) | - | - | - |
| SimpleArray | 10000007 | Plain array (workflow) | - | - | - |
| ObjectArray | 10000008 | Object array (workflow) | - | - | - |
Key field type handling
1. Option fields (SingleSelect/MultipleSelect)⭐⭐⭐
Write: Must pass an array of option keys
{
"id": "customer_type",
"value": ["74c7b607-864d-4cc4-b401-28acba2636e9"] // 选项key
}
Read: Returns an array of objects containing key and value
{
"customer_type": [
{
"key": "74c7b607-864d-4cc4-b401-28acba2636e9",
"value": "成交客户"
}
]
}
⚠️ Key point:
- Even for single-select, use an array
["key"] - Do not pass display text
["成交客户"], must use key - When filtering, you must use key, not display text
2. Attachment field (Attachment)⭐
Write: Supports URL and base64
{
"id": "attachments",
"type": "0", // 0=覆盖, 1=追加
"value": [{
"name": "产品宣传册.pdf",
"url": "https://example.com/brochure.pdf"
}]
}
Read: Returns an array of attachment objects
{
"attachments": [{
"file_id": "...",
"file_name": "...",
"downloadUrl": "https://...", // ⚠️ 使用 downloadUrl
"file_size": 2048576
}]
}
⚠️ Important note:
- Attachment upload is asynchronous and usually takes 5-10 seconds
- An API returning success does not mean the attachment upload is complete
- Use
downloadUrlinstead ofurl
3. Relation field (Relation)⭐⭐⭐
Write: Pass an array of record IDs
{
"id": "related_customer",
"value": ["945e6503-3823-4e91-9d84-a53f8bdd6fc5"] // 记录rowid
}
Read: Returns an array of objects (containing only sid and name)
{
"related_customer": [{
"sid": "945e6503-3823-4e91-9d84-a53f8bdd6fc5",
"name": "明道云科技有限公司"
}]
}
Get complete related data:
// 方法1: 使用专用 API
GET /v3/app/worksheets/{worksheet_id}/rows/{row_id}/relations/{field_id}
// 方法2: 使用 sid 查询目标表
POST /v3/app/worksheets/{target_worksheet_id}/rows/list
{
"filter": {
"type": "group",
"logic": "AND",
"children": [{
"type": "condition",
"field": "rowid", // ⚠️ 使用系统字段 rowid
"operator": "in",
"value": ["sid1", "sid2"] // 传入关联记录的 sid
}]
}
}
Detailed specification: Refer to references/hap-api-usage-guide.md Section 6
4. Collaborator field (Collaborator)
Write: Pass an array of user IDs
{
"id": "owner",
"value": ["user-account-id-123"] // 用户ID,不是用户名
}
Get user IDs:
POST /v3/users/lookup
{
"name": "张三" // 精确匹配姓名
}
5. Number field (Number)
Write: Pass a number type
{
"id": "annual_budget",
"value": 1000000.50
}
Read: Returns a string
{
"annual_budget": "1000000.50"
}
⚠️ Note: Write a number, read a string
Detailed specification: Refer to references/hap-api-usage-guide.md Sections 2, 3
triggerWorkflow parameter details ⭐Important
triggerWorkflow The parameter controls whether worksheet-related workflows are triggered during data operations.
Applicable scope:
- ✅ Create record
- ✅ Batch create
- ✅ Update record
- ✅ Batch update
- ✅ Delete record
- ✅ Batch delete
Parameter description:
| Parameter value | Description | Default value | Use case |
|---|---|---|---|
true |
Trigger workflow | ✅ Yes | Normal business operations, automated processes need to be executed |
false |
Do not trigger workflow | ❌ No | Data migration, batch initialization, test data |
✅ Scenarios where it should be set to true :
- Normal business operations (users submitting forms, updating status, etc.)
- Operations that require automated processing
❌ Scenarios where it should be set to false :
- Data migration and import
- Batch data initialization
- Scheduled sync tasks
- Testing and debugging
Performance impact:
triggerWorkflow: false- Fast API response, usually < 500mstriggerWorkflow: true- Needs to wait for workflow execution, may take 1-5 seconds
Detailed description: Refer to references/hap-api-usage-guide.md Section 3.2
Common pitfalls and solutions ⭐⭐⭐
Pitfall 1: Using display text to filter option fields
Problem: Filtering single-select/multi-select fields returns empty results
Wrong example:
{
"field": "customer_type",
"operator": "eq",
"value": ["成交客户"] // ❌ 使用了显示文本
}
Correct approach:
{
"field": "customer_type",
"operator": "eq",
"value": ["74c7b607-864d-4cc4-b401-28acba2636e9"] // ✅ 使用选项key
}
Solution:
- Query the worksheet structure during initialization and cache the option mapping
- Or first query a record and get the key from the returned data
- Build a value → key mapping table
Pitfall 2: Numeric field filtering uses numeric type
Problem: Numeric filtering returns no results or reports an error
Incorrect example:
{
"field": "annual_budget",
"operator": "gt",
"value": [1000000] // ❌ 数字类型
}
Correct approach:
{
"field": "annual_budget",
"operator": "gt",
"value": ["1000000"] // ✅ 字符串数组
}
Mnemonic: The value of a filter condition is always a string array
Pitfall 3: Using an incorrect operator for relation fields
Problem: Using an incorrect operator to filter relation fields
Incorrect example:
{
"field": "related_customer",
"operator": "belongsto", // ❌ V3 API 不支持 belongsto;关联字段应用 in/eq
"value": ["customer-id"]
}
Correct approach:
{
"field": "related_customer",
"operator": "in", // ✅ 关联字段用 in 或 eq
"value": ["customer-row-id"] // 传入关联记录的 rowid 数组
}
Pitfall 4: N+1 query problem with relation fields
Problem: Querying related data one by one on the list page
Incorrect example:
// ❌ 性能灾难:100个产品 = 1 + 100 = 101次请求
const products = await getProductList(); // 1次请求
for (const product of products) {
const categoryId = product.category[0].sid;
const category = await getCategoryById(categoryId); // 100次请求!
}
Correct approach: Batch query
// ✅ 性能优化:100个产品 = 1 + 1 = 2次请求
const products = await getProductList(); // 1次请求
// 收集所有分类ID
const categoryIds = new Set();
products.forEach(p => {
if (p.category && p.category.length > 0) {
categoryIds.add(p.category[0].sid);
}
});
// 批量查询所有分类
const categories = await getRows('category-worksheet-id', {
filter: {
type: 'condition',
field: 'rowid',
operator: 'in',
value: Array.from(categoryIds)
}
}); // 1次请求
// 建立映射
const categoryMap = {};
categories.rows.forEach(cat => {
categoryMap[cat.rowid] = cat;
});
Detailed description: Refer to references/hap-api-usage-guide.md Section 7
Performance optimization recommendations
1. Query optimization
- Use pagination appropriately: pageSize should not exceed 1000
- Specify return fields: Use the fields parameter to return only the fields you need
- Use field IDs: Better query performance than aliases
- Avoid excessive nesting: Keep Filter nesting within 2 levels
- Make good use of views: For complex filtering, create a view first, then query the view
2. Batch operation optimization
- Batch create: At most 100 records at a time
- Batch update: At most 100 records at a time
- Including relation fields: Reduce to 30-50 records per batch
- Including attachments: Recommended to handle separately, do not batch
- Delay between batches: 1-2 seconds between each batch
3. Relation field optimization
- Reduce nested queries: Use the get_record_relations API to retrieve all at once
- Batch query: Avoid the N+1 query problem
- Cache related data: Frequently accessed related data can be cached
- Control showFields: Display only necessary fields to reduce data volume
Detailed description: Refer to references/hap-api-usage-guide.md Section 8
🤖 AI assistant usage guide
When users need to call the HAP V3 API, the AI assistant should follow these principles:
1. Automatically extract authentication keys
Priority order:
-
Prefer extracting from MCP configuration(Recommended)
- Read the configured HAP MCP configuration
- Find
hap-mcp-*configuration - Extract from the URL
HAP-AppkeyandHAP-Sign - If multiple configurations are found, ask the user which application to use
-
User provides manually
- If no MCP configuration is found, prompt the user to provide Appkey and Sign
- Or guide the user to configure MCP first
-
Guide MCP configuration
- If the user has MCP configuration information, help the user configure it in the editor/client being used
- Then extract the key from the configuration
2. Configure request headers
After extracting the key, automatically configure the request headers:
const headers = {
'Content-Type': 'application/json',
'HAP-Appkey': extractedAppkey, // 从 MCP 配置提取
'HAP-Sign': extractedSign // 从 MCP 配置提取
};
3. Handle multiple applications
If the user has configured multiple HAP MCPs:
- Explicitly specify the application name: If the user mentions a specific application name, use the corresponding configuration
- Ask the user: If not specified, list all configured applications and let the user choose
- Use by default: If there is only one configuration, use it directly
4. Error handling
- Configuration does not exist: Prompt the user to configure MCP first or provide the key manually
- URL parsing failed: Check whether the URL format is correct
- Missing parameters: Check whether both Appkey and Sign exist
- Permission issue: If the configuration file cannot be read, prompt the user to check file permissions
5. Practical operation examples
Scenario: The user says "help me call the HAP API to query data"
AI operation process:
- Read the configured HAP MCP configuration file (the path depends on the editor/client being used, such as its global
settings.json) - Find
mcpServersin thehap-mcp-*configuration - If a configuration is found, extract Appkey and Sign from the URL
- If multiple configurations are found, ask the user which application to use
- Use the extracted key to configure the API request headers
- Execute the API call
Scenario: The user provided MCP configuration information
AI operation process:
- First help the user add the MCP configuration to the MCP configuration file of the editor/client being used
- Then extract Appkey and Sign from the configuration
- Use the extracted key for subsequent API calls
Best practices
1. Initialization phase
Required actions:
- Query the structure of all worksheets
- Cache the key-value mappings of all option fields
- Cache worksheet IDs and field IDs
- Establish a user name→ID mapping
Example code:
// 1. 获取工作表结构
const structure = await getWorksheetStructure(worksheetId);
// 2. 提取选项字段映射
const optionMaps = {};
structure.fields.forEach(field => {
if (field.type === 'SingleSelect' || field.type === 'MultipleSelect') {
optionMaps[field.id] = {};
field.options.forEach(opt => {
optionMaps[field.id][opt.value] = opt.key; // value → key
});
}
});
// 3. 使用时查找key
const customerTypeKey = optionMaps['customer_type']['成交客户'];
2. Query phase
Recommendations:
- Prefer using field IDs instead of aliases
- Option fields must use key, convert in advance
- Use strings for the value of numeric fields
- Use the in or eq operator for related fields (value is an array of rowid)
- Set pageSize reasonably (recommended 100-500)
3. Write phase
Checklist:
- The value of the option field is in array format
- The option field passes key, not value
- Numeric fields pass a numeric type
- Related fields pass rowid
- Member fields pass accountId
- Attachment fields have the type parameter set
4. Error handling
Common error codes:
error_code: 1- Successerror_code: -1- Failure, check error_msgerror_code: 4- Insufficient permissionserror_code: 10- Parameter error
Recommendations: All API calls must check error_code and success
Detailed explanation: Refer to references/hap-api-usage-guide.md Section 9
Common API Endpoint Quick Reference
| Scenario | API Endpoint | Key Parameters |
|---|---|---|
| Create Worksheet | POST /v3/app/worksheets |
fields |
| Add Field | POST /v3/app/worksheets/{id} |
addFields |
| Create Record | POST /v3/app/worksheets/{id}/rows |
fields |
| Batch Create | POST /v3/app/worksheets/{id}/rows/batch |
rows |
| Query Records | POST /v3/app/worksheets/{id}/rows/list |
filter, sorts |
| Update Record | POST /v3/app/worksheets/{id}/rows/{row_id} |
fields |
| Batch Update | PUT /v3/app/worksheets/{id}/rows/batch |
rowIds, fields |
| Delete Record | DELETE /v3/app/worksheets/{id}/rows/{row_id} |
permanent |
| Batch Delete | DELETE /v3/app/worksheets/{id}/rows/batch |
rowIds, permanent |
| Pivot Analysis | POST /v3/app/worksheets/{id}/rows/pivot |
rows, values |
| Find User | POST /v3/users/lookup |
name |
| Find Department | POST /v3/departments/lookup |
name |
| Get Region | POST /v3/regions |
search, id |
Reference Resources
Core Documentation
references/hap-api-usage-guide.md- Complete Guide to HAP V3 API Usage Specifications- Quick Start - API Usage Flow
- Worksheet Creation Specifications
- Detailed Explanation of Field Type Parameters
- Create/Update Record Specifications (Detailed Explanation of triggerWorkflow)
- Query Filter Specifications (Filter Object Structure, Operator List)
- Data Pivot Analysis Specifications
- Complete Guide to Relation Fields
- Common Pitfalls and Solutions
- Performance Optimization Recommendations
- Best Practices Summary
Online Documentation
Related Skills
- HAP Frontend and Backend Project Setup Guide - Build an Independent Website Using HAP as a Database
- HAP View Plugin Development Guide - Develop HAP Custom View Plugins
Key Concepts Quick Reference
Field Types (type):
- Basic:
Text,Number,Date,Time - Selection:
SingleSelect,MultipleSelect - Relation:
Relation,Collaborator,Department - Other:
Attachment,Rating
Filter Operators (operator):
- Comparison:
eq,ne,gt,gte,lt,lte - Text:
contains,startswith,endswith - Range:
between,in - Relation:
in/eq(value is an array of rowids) - Department:
in/eq/notin, etc. (see the field type comparison table for details; V3 API has no belongsto) - Null:
isempty,isnotempty
subType Parameter:
- Collaborator:
0=single select,1=multiple select - Relation:
1=single,2=multiple - Time:
1=hour:minute,6=hour:minute:second - Date:
3=year-month-day,6=year-month-day hour:minute:second
Troubleshooting Checklist
No filter results:
- Did the option field use key instead of value?
- Did the numeric field value use a string?
- Did the relation field use in/eq + rowid?
- Is the Filter nesting more than 2 levels deep?
- Is the field ID correct?
Create/update failed:
- Are all required fields provided?
- Does the dataSource of the relation field exist?
- Is the key of the option field valid?
- Is the accountId of the member field valid?
- Is the numeric field out of range?
Data anomaly:
- Has the attachment been waited for 5-10 seconds?
- Is the date precision subType correct?
- Has the associated record been deleted?
Skill version: v2.0
Last updated: 2026-01-11
Based on: HAP API V3
Detailed specification: Reference references/hap-api-usage-guide.md