When to use this endpoint

Use EmailTemplate_saveData only when the sender must contain {{USER_EMAIL}} or {{CREATED_BY_EMAIL}}. For an ordinary email address, use the editor-backed EmailTemplate_save route.

Authentication and permissions

The request must authenticate with signed API-key fields or a logged-in CRM session. The handler requires login and performs no additional page or role-permission check.

The read or write is limited to the authenticated tenant. Notice endpoints that say “current user” use the authenticated session user ID within that tenant.

Parameters

ParameterTypeRequiredDescription
idInteger-compatibleYesExisting template ID. It must convert to an integer of at least 1.
nameStringYesTrimmed nonblank name, unique across other active and archived templates.
bodyHTML stringYesComplete body. Script, iframe, and meta elements are removed; blank becomes {{BODY}}; inline base64 images are uploaded and rewritten.
subjectStringYesTrimmed subject of at most 100 bytes. Blank is accepted.
from_emailEmail or placeholder stringYesTrimmed sender. Blank falls back to tenant setting default-from-email. A value passes when it is a valid email or contains {{USER_EMAIL}} or {{CREATED_BY_EMAIL}} anywhere in the string.
is_defaultInteger-compatibleYesStored integer default flag. Newly setting a row truthy clears current defaults first.
typeInteger-compatibleNoUnvalidated legacy category; defaults to 0.
form_idInteger-compatibleWhen type is 7Stored at meta.form_id only for type 7; it is not checked against the forms table.

Example request

$result = FM_api('EmailTemplate_saveData', [
	'id' => '152004',
	'name' => 'Assigned-user message',
	'body' => '<p>Hello {{CUSTOMER_NAME}}</p>',
	'subject' => 'Your service update',
	'from_email' => '{{USER_EMAIL}}',
	'is_default' => '0',
	'type' => '1',
]);

Example response

{"ok":1}

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"}id is absent or converts below 1.
{"error":"email template does not exist"}No template has the numeric ID.
{"error":"subject too long. max length 100"}The trimmed subject exceeds 100 bytes.
{"error":"no name parameter"}The trimmed name is blank.
{"error":"from_email should be an email address"}The final sender is neither a valid email nor a string containing one of the two recognized placeholder tokens.
{"error":"cannot save because that name is already used by another template"}Another active or archived template has the same name.

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

Behaviour and edge cases

  • Except for sender validation, behavior matches EmailTemplate_save: direct access makes the five editor fields operationally required, HTML is sanitized, data images are processed before later validation, and blank bodies become {{BODY}}.
  • Every save replaces metadata with only the form association for type 7, or with [] for other types.
  • A newly truthy default clears all existing defaults; a row already marked default does not trigger repair of other duplicate defaults.
  • No direct production caller was found, so integrations should not assume this route is interchangeable with the settings UI’s save call.

Side effects

  • May upload inline images, remove unsafe HTML elements, clear other templates’ default flags, and update the template row before returning success.
  • An error after image processing can leave uploaded files. The final update is unchecked and no generic history or explicit cache invalidation is performed.

See it in Fieldmotion

CRM1

No direct CRM1 production caller was found; CRM1 template settings use EmailTemplate_save.

CRM2

No direct CRM2 production caller was found; CRM2 template settings also use EmailTemplate_save.

Related endpoints