Skills
Import skills and user assignments
/a/Skills_import
Create or update skills and add user assignments from CRM2’s versioned spreadsheet-import row format.
When to use this endpoint
Use Skills_import through CRM2’s Skills import widget after mapping columns to ID, Name, Description, and/or User IDs. It processes the complete batch and returns row errors plus assignment warnings.
Authentication and permissions
The request must authenticate with signed API-key fields or a logged-in CRM session, and the identity must pass Core_isClientAdmin().
All skill/user lookups, writes, assignments, and import logging use the authenticated tenant.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
v | Integer string | Yes | Import protocol version; it must integer-convert to 2 or greater. |
map | JSON array | Yes | Column descriptors using to values id, name, description, or user_ids. Unknown destinations are ignored. Native arrays are not accepted by the unconditional JSON decoder. |
rows | JSON array of arrays | Yes | Positional rows corresponding to map. Missing cells become empty strings; each mapped value is string-cast and trimmed. |
filename | String | No | Nonblank source filename stored in import-log metadata. It does not affect matching or processing. |
Example request
$result = FM_api('Skills_import', [
'v' => '2',
'map' => json_encode([
['to' => 'id'],
['to' => 'name'],
['to' => 'description'],
['to' => 'user_ids'],
]),
'rows' => json_encode([
['', 'Electrical testing', 'Qualified tester', '92556, 92557'],
]),
'filename' => 'skills.csv',
]);
Example response
{
"ok": 1,
"created": 1,
"edited": 0,
"errors": [],
"warnings": []
}
Each row error is [zeroBasedRowIndex, [{"msg":"...","val":value}]]. Warnings are plain strings for invalid/missing user IDs or users already assigned.
Errors and unusual responses
| Response | Condition |
|---|---|
{"error":"not logged in"} | No authenticated tenant context is available. Invalid signed credentials can be rejected by the dispatcher before the handler runs. |
{"error":"not an admin"} | The authenticated caller is not a client administrator. |
{"error":"missing or invalid parameter: v"} | The version is below 2. |
{"error":"missing or invalid parameter: map or rows"} | Either key is absent, invalid JSON, or does not decode to an array. |
Row error: missing or invalid skill name | The mapped name is absent or blank after trimming. |
Row error: skill name is too long, 100 character limit | The trimmed name exceeds 100 bytes. |
Row error: skill does not exist | A positive mapped ID does not identify a tenant skill. |
Legacy application errors may be returned with HTTP 200. Check the decoded response for error, not only the HTTP status.
Behaviour and edge cases
- A positive mapped ID is used first. Without one, exact name matching under the tenant collation selects an existing skill; otherwise a new skill is created through
Skill_new. - Existing matches are counted as edited even if name/description values do not materially change. Description is updated only when that column is mapped; a mapped blank clears it.
- Comma-separated user IDs are trimmed and exact duplicate strings removed. Invalid/nonexistent users and existing assignments produce warnings; new assignments use multiplier
1. - Rows with a skill error skip assignments. There is no row-count limit or rollback.
Side effects
- Creates or updates skills, setting
last_editedto current Unix time; new skills also receive currentcdate. Direct import updates do not explicitly invalidate cache or write field history. - New assignments replace no existing data:
User_setSkillinserts a user/skill row at multiplier1only after both records are revalidated. - Always writes one import-log row of type
12, even for an empty batch or one where every row fails, with create/edit counts, current user, generated import ID, and optional filename.
See it in Fieldmotion
CRM1
A production-source search found no CRM1 caller. CRM1 provides manual skill creation/assignment rather than this batch import.
CRM2
Open Users → Skills, choose Import, map the four supported columns, and run it. The widget sends v=2 and JSON-encoded map/rows.
Related endpoints
Skill_newcreates each previously unmatched skill inside this flow.Skill_listUserscan verify direct assignments in the CRM1-shaped response.