Communications
Save a template with sender placeholders
/a/EmailTemplate_saveData
Save a complete email template while allowing legacy dynamic sender-address placeholders.
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
| Parameter | Type | Required | Description |
|---|---|---|---|
id | Integer-compatible | Yes | Existing template ID. It must convert to an integer of at least 1. |
name | String | Yes | Trimmed nonblank name, unique across other active and archived templates. |
body | HTML string | Yes | Complete body. Script, iframe, and meta elements are removed; blank becomes {{BODY}}; inline base64 images are uploaded and rewritten. |
subject | String | Yes | Trimmed subject of at most 100 bytes. Blank is accepted. |
from_email | Email or placeholder string | Yes | Trimmed 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_default | Integer-compatible | Yes | Stored integer default flag. Newly setting a row truthy clears current defaults first. |
type | Integer-compatible | No | Unvalidated legacy category; defaults to 0. |
form_id | Integer-compatible | When type is 7 | Stored 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
| 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":"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
EmailTemplate_saverequires a conventional valid sender address.EmailTemplate_getreads the stored result.