Authoritative Tutorial on the "Query User List" Interface of Xiaoman OKKICRM
What Problem This Interface Solves
In the integration between Xiaoman OKKICRM and Kingdee Cosmic, personnel master data is the foundation of every business document: sales order owners, customer ownership, opportunity follow-up, and task assignment all rely on "people". The /v1/user/list interface pulls user/employee master data from Xiaoman into the integration platform in one go, serving as the reference base for downstream document synchronization. Its typical value is to centralize scattered CRM personnel records and prevent issues like "missing salesperson" or "wrong department" in downstream systems.
Interface Capability Overview
- Authentication: Xiaoman OKKICRM uses the OAuth 2.0 standard AccessToken model. The integration platform must obtain and cache the token, refreshing it proactively before expiry.
- Request Method: HTTP GET, endpoint
/v1/user/list, supporting filters bydepartment_id,enable_flag,last_modified_time, etc. - Response Structure: JSON object. Core fields reside in the
data.listarray, with top-levelcode,message, andtotal_count. Pagination typically usespageandpage_size, with an empirical single-page cap of 200 records. - Pagination / Incremental: Supports timestamp-based incremental sync (
last_modified_timecursor). The scheduled task runs daily at 03:20 (20 3 * * *). Strategy type is QUERY_ONLY (pure query, with the target configured as a "write no-op").
Typical Field Mappings
| Field Name | Type | Meaning | Practical Notes |
|---|---|---|---|
| user_id | string | User unique primary key | The "anchor" for cross-system mapping; must serve as the unique identifier and never be confused with nickname |
| nickname | string | Nickname / display name | Commonly displayed on business documents; may be an alias, different from the formal full name |
| employee_no | string | Employee business code | Prefer this field (not user_id) when reconciling with Kingdee employee codes |
| full_name | string | Full name | Concatenation of family_name + second_name; used in formal contexts |
| family_name / second_name | string | Family name / given name | Split fields suit internationalization; concatenate via template if the target system takes only one column |
| email / user_mobile / ames_email | string | Internal contact info | Distinguish from external_*; map per the target system's employee card structure |
| external_email / external_mobile / external_fax / external_address / external_other | string | External contact info | Despite many names, often empty; filter nulls to avoid dirty data |
| gender / position | string | Gender / position | Values are dictionary-constrained; verify enum consistency before mapping |
| department_id / department_name | string | Department | Used to filter sync by department or build org-structure reconciliation |
| enable_flag | string | Enable flag | Recommend syncing only users with enable_flag=1; disabled accounts should not flow downstream |
How to Configure on Qeasy
On the Qeasy Data Integration Platform, this interface is typically encapsulated via the "Xiaoman OKKICRM Adapter". We only need to configure the datasource connection (client_id, client_secret, callback URL) and the extraction strategy. Qeasy's field mapper automatically reads source metadata, listing key fields like user_id, nickname, and employee_no in the mapping panel — just drag and drop to generate the target (Kingdee Cosmic employee) reconciliation. For pure query strategies, set the target to "Write No-Op" so that data stays in Qeasy's staging table for other strategies (e.g., sales order sync) to look up by employee_no.
Cross-Project Practical Tips
- Separate primary key from business code: Across multiple customer projects we always use
user_idas the unique key andemployee_noas the business code, avoiding master-data drift caused by nickname changes. - Filter enable_flag upfront: Add
enable_flag=1to Qeasy's source-side filter so disabled accounts are blocked from the sync chain, reducing downstream cleaning effort. - Dual-track nickname and full name: Downstream business documents usually need to "display nickname + store full name"; persist both rather than only one.
- Group contact info when mapping: Internal (email/user_mobile/ames_email) and external (external_*) map to different columns on the Kingdee employee card — do not lump them together.
- Use timestamp for incremental, not page numbers: Even though pagination is supported, in production prefer the
last_modified_timecursor for more reliable checkpoint resumption. - Schedule at off-peak hours: A crontab of 03:20 avoids business peak hours and reduces rate-limit pressure on the Xiaoman API.
Pitfall Recap
- Pitfall 1: Treating nickname as the primary key — In one project, the nickname was used directly as the downstream relation key, and after an employee changed their name all historical documents lost linkage. The safe approach: always use
user_idas the primary key;nicknameis for display only. - Pitfall 2: No filter on enable_flag — The downstream Kingdee employee table was flooded with disabled accounts, causing sales order assignment to pick "null" persons. Always filter
enable_flag=1on the source side. - Pitfall 3: Empty external contact fields flooding the target —
external_*is empty for many users; syncing them pollutes the target table. Apply a non-null check before writing, or skip mapping entirely. - Pitfall 4: Pagination loop missing pages — When
total_countexceeds one page, only the first page was fetched. In Qeasy, ensure the paginator walks to the end, or switch to incremental mode. - Pitfall 5: Token expiry not refreshed — Xiaoman tokens expire in 2 hours by default; a long-running script in one project hit 401 midway. Qeasy typically auto-renews; self-built scripts must add refresh logic.
When to Use
Enable this interface whenever the business needs to "sync CRM personnel records to the ERP as salesperson/owner master data"; it is especially suitable for scenarios where sales orders, customers, opportunities, and tasks share one personnel dictionary. It is not suitable for pure display integrations or one-way write-back scenarios — those require write interfaces, while this one is query-only.