When to use this endpoint

Use EmailTemplate_save for CRM1 or CRM2 email-template editor submissions. It is the dedicated full-save contract and should be preferred over generic mapped updates.

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 template name, unique across other active and archived templates under the database collation.
bodyHTML stringYesComplete body. Script, iframe, and meta elements are removed. A blank result becomes {{BODY}}; inline base64 images are uploaded and their src values are replaced.
subjectStringYesTrimmed subject, at most 100 bytes as measured by strlen. Blank is accepted.
from_emailEmail stringYesTrimmed sender. Blank input falls back to nonblank tenant setting default-from-email; the final value must pass PHP email validation. Placeholder sender codes are not accepted by this route.
is_defaultInteger-compatibleYesStored integer default flag. A false-like value clears this row’s flag; a newly truthy row clears existing defaults first.
typeInteger-compatibleNoLegacy template category; defaults to 0. The endpoint accepts any integer and does not validate the category list.
form_idInteger-compatibleWhen type is 7Stored as meta.form_id only for type 7. It is integer-converted and the referenced form is not checked.

Example request

$result = FM_api('EmailTemplate_save', [
	'id' => '152004',
	'name' => 'Service completion email',
	'body' => '<p>Hello {{CUSTOMER_NAME}}</p>',
	'subject' => 'Your service report',
	'from_email' => 'service@example.test',
	'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"}Neither the submitted sender nor the tenant fallback is a syntactically valid email address.
{"error":"cannot save because that name is already used by another template"}Another template, including an archived one, 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

  • Although only id has an explicit presence check, the implementation directly reads name, body, subject, from_email, and is_default. Treat all five as required to avoid runtime warnings and unintended blank values.
  • Every save replaces all template metadata with {"form_id":...} for type 7, or [] for every other type. Unrelated metadata keys are lost.
  • If the row is changing from non-default to truthy default, all current defaults are cleared first. If the row was already default, the route does not repair any additional rows that are also marked default.
  • Inline data:image...;base64,... images are stored below the tenant’s emailtemplate_images/<id> path. Images over twice their HTML width or height are resized to exactly twice both declared dimensions and emitted as PNG.
  • The final database-update result is not checked; after validation, the endpoint returns success even if that statement fails.

Side effects

  • May upload file records/content for inline images, remove unsafe HTML elements, clear other templates’ default flags, and update the selected row.
  • This legacy route does not write generic field history or explicitly invalidate the email-template cache.

See it in Fieldmotion

CRM1

Open Settings → Email Templates in CRM1 and filter browser developer tools for the endpoint name. Open a template, edit its fields in the rich-text dialog, and choose Save.

CRM2

Open Settings → Email Templates in CRM2 and filter browser developer tools for the endpoint name. Open a template card, edit it, and save the dialog.

Related endpoints