When to use this endpoint

Use Accounts_import for the Finance-page spreadsheet import after mapping source columns. It updates matches and inserts nonmatches one row at a time.

Authentication and permissions

The request must authenticate with signed API-key fields or a logged-in CRM session. The handler calls the normal login guard but performs no additional Finance-page, client-admin, role, create, edit, or delete permission check.

All reads and writes use the authenticated tenant. CRM1 and CRM2 decide whether to show finance controls, but these handlers do not repeat those client-side checks.

Parameters

ParameterTypeRequiredDescription
vInteger-compatibleYesImport contract version. It must integer-convert to at least 2.
mapJSON array of objectsYesPositional column map. Each object’s nonempty to can be id, nominal_code, name, display_name, category, category_group, description, or tax_rate; other targets are ignored.
rowsJSON array of arraysYesSpreadsheet rows whose indexes correspond to map. Missing cells become empty strings.

Example request

$result = FM_api('Accounts_import', [
	'v' => 2,
	'map' => json_encode([
		['to' => 'nominal_code'],
		['to' => 'name'],
		['to' => 'category'],
		['to' => 'category_group'],
		['to' => 'tax_rate'],
	]),
	'rows' => json_encode([
		['4000', 'Sales', 'Standard VAT', 'Income', '20'],
	]),
]);

Example response

{"ok":1,"time":0,"inserts":1,"updates":0}

Errors and unusual responses

ResponseCondition
{"error":"not logged in"}No authenticated tenant context is available. Invalid signed credentials can be rejected by the dispatcher before the handler runs.
{"error":"missing or invalid parameter: v"}The contract version is absent or below 2. This check occurs before authentication.
{"error":"missing or invalid parameter: map"}The parameter is absent or its JSON does not decode to an array.
{"error":"missing or invalid parameter: rows"}The parameter is absent or its JSON does not decode to an array.
{"error":"The import map is missing the \"...\" field."}Any of nominal_code, name, category, or category_group lacks a nonempty mapping. Multiple messages are newline-separated.

Legacy application errors may be returned with HTTP 200. Check the decoded response for error, not only the HTTP status.

Behaviour and edge cases

  • Each tax group is found by exact name or created. A reused group’s description is overwritten when it differs.
  • Each tax type is found globally by exact name, not by group. It is then moved to the imported group and its tax rate is overwritten. Decimal tax input is integer-converted, so 20.5 becomes 20.
  • An account match uses ID, then code, then name. A nonmatch is inserted even when a particular row’s required-looking values are blank; required fields are checked only in the map.
  • A category link is inserted without checking for an existing identical link, so repeated imports can create duplicate manymany rows.
  • time is elapsed whole seconds. The endpoint returns aggregate insert/update counts but no row-level result.

Side effects

  • Creates or updates category groups, categories, accounts, and account/category links.
  • Advances account/category last_edited timestamps and account timestamps when links are added. Group rows have no timestamps.

See it in Fieldmotion

CRM1

Open Settings → Finance. CRM1 loads and edits the Chart of Accounts, Tax Types, and Tax Groups from this endpoint family; filter browser developer tools for the exact function name. Choose Import Accounts, map the required columns, and complete the import.

CRM2

Open Settings → Finance. CRM2 loads the three finance tables and saves them as complete snapshots; filter browser developer tools for the exact function name. Use the Import action on the Chart of Accounts tab; CRM2 passes v=2 with the same required mappings.

Related endpoints