When to use this endpoint

Use after configuring columns in an import/export dialog. A nonpositive ID creates a map; a positive ID replaces an existing one. Fetch the saved row with Map_get before editing if its metadata must be preserved.

Authentication and permissions

Authenticate with signed API-key fields or a logged-in CRM session. The handler requires a logged-in user but no map-management, role or ownership permission. Every saved map is tenant-wide.

Parameters

ParameterTypeRequiredDescription
idInteger stringYes0 or -1 creates; a positive integer updates an existing map. Values below -1 cannot edit defaults. Blank/non-numeric IDs are rejected.
typePositive integer stringYes1–32767, with no business-type enum allowlist. Customer export uses 7; use the type supplied by the calling widget.
nameStringYesNonempty, at most 64 bytes and 64 characters. Not trimmed. Creation suffixes duplicate names within a type and shortens the base to keep the result within 64 bytes.
mapsNative JSON value or JSON stringYesValid JSON, at most 65535 encoded bytes. Normal widget value is an array of from/translate/to column objects. JSON syntax is checked, not translation semantics.
pre-editBoolean or 0/1 or true/false stringNoStored as meta.pre_edit. Defaults 0 on creation; omission preserves the stored option on update.
otherNative JSON value or JSON stringNoStored as meta.other. Defaults an empty array on creation; omission preserves the stored option on update. Invalid JSON is rejected.

Example request

$map = FM_api('Map_save', [
	'id' => '0',
	'type' => '7',
	'name' => 'Customer names',
	'maps' => json_encode([['from' => 'name', 'translate' => (object)[], 'to' => 'Name']]),
	'other' => json_encode(['export_sort_by' => 'name', 'export_sort_dir' => 'asc']),
]);

Example response

{"ok":1,"id":1042,"name":"Customer names"}

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: id"}Invalid ID; equivalent validation errors name maps, type, name, pre-edit or other.
{"error":"cannot edit default maps"}ID is below -1.
{"error":"maps is too large. 65535 bytes max"}Encoded mapping exceeds the limit.
{"error":"name is too long. 64 bytes max"}Name exceeds 64 bytes while within the character limit.
{"error":"no such map"}Positive update ID does not exist.
{"error":"configuration read failed"}A required database read fails; no write is committed.
{"error":"configuration write failed"}Persistence or checked history fails; the transaction rolls back.
{"error":"configuration transaction failed"}Transaction begin or commit fails; no success is reported.

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

Behaviour and edge cases

  • Creation allocates a free name within the requested type under a tenant write lock. Duplicate names get numeric suffixes; the base is shortened without splitting Unicode characters when needed. Updates retain the existing non-deduplicating rename behavior.
  • Updates replace maps, type and name, preserve creation time, and preserve omitted metadata options and unknown metadata properties. Supplied metadata options replace those properties rather than merge their contents.
  • Maps and other must be valid JSON. The server does not validate column mappings or export-sort semantics.

Side effects

  • Creation sets cdate to current Unix seconds; update preserves it. Saves request the maps cache marker and record checked save history in the same transaction.
  • No notification or dependent business data is changed.

See it in Fieldmotion

CRM1

Open an import or export dialog, then use its saved-map selector. Filter browser Network requests for this endpoint; widgetImport.js and widgetExport.js implement the workflow. Choose Save; import sends pre-edit, while export sends JSON other options.

CRM2

Open the CRM2 import/export dialog and use its saved-map selector. The import widget and widgetExportCRM2.js use the same route and stored JSON-string contract. Save uses the same import/export parameter differences.

Related endpoints

  • Map_get reloads the saved JSON strings.
  • Maps_list refreshes the selector after saving.