When to use this endpoint

Use after assembling editor values that another document or recurrence can reuse. The caller owns the payload schema and must omit object-specific IDs or dates it does not want reused. The server stores the supplied payload; it does not clone the source document.

Authentication and permissions

Authenticate with signed API-key fields or a logged-in CRM session. Template_get, Template_new, Template_setObj and Templates_get require an authenticated tenant context; Template_delete and both table handlers also call the login guard. There is no handler-level administrator, page, role, creator or ownership check.

Templates are shared within the authenticated tenant, not private to created_by. There is no user, department, feature-setting or active/deleted filter. The dispatcher also applies its normal account, authentication and team-access checks; the shared table predicate adds no template-specific row restriction.

Parameters

ParameterTypeRequiredDescription
nameStringYesTrimmed, nonblank name, at most 100 Unicode characters. Duplicate names are allowed; no uniqueness lookup is performed.
typeIntegerYesInteger-converted positive object type; omitted/blank/null/zero fail. Not an allowlisted enum on the server.
objJSON textYesNonblank string, trimmed before storage. JSON-encode the editor’s object before signing. JSON syntax is validated before storage, but its schema is not. A native PHP array is rejected; encoded JSON scalars also pass syntax validation.

Example request

$created = FM_api('Template_new', [
	'name' => 'Standard quote',
	'type' => '3',
	'obj' => json_encode(['notes' => 'Reusable quote notes']),
]);

Example response

{"ok":1,"id":1042}

Success requires a positive insert-helper ID. A failed or throwing insert returns an error without ok/id. An interrupted transport can still leave the caller unsure whether a successful insert committed.

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: name"}Missing/null/blank name after trimming.
{"error":"parameter too long: name. max length 100 characters"}Trimmed name exceeds 100 characters.
{"error":"Unable to create template"}The insert fails, throws, or returns no positive ID.
{"error":"missing or invalid parameter: type"}Integer-converted type is below 1.
{"error":"missing or invalid parameter: obj"}Missing, non-string, blank or malformed JSON payload.

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

Behaviour and edge cases

  • The CRM2 enum defines 1=recurrence, 2=job, 3=quote, 4=invoice and 5=opportunity. The PHP handlers accept any positive integer, not just that enum. These are saved input presets, not email templates or PDF/Word document designs.
  • The payload is stored whole; no field defaults, referenced-record checks, duplicate detection or idempotency key is applied. Retrying creates another row. Creation does not select a default preset or update a source document.
  • No direct mobile-app or m-service caller for this template family was found in the source search. The CRM2 widget’s payload is client-defined; storing it does not validate that another document endpoint will accept every field.

Side effects

  • Inserts the tenant template with current Unix-second cdate/last_edited and the authenticated user as created_by. No explicit Core_log, deletion audit, event, email, queue or cache-invalidation option is invoked by this handler.

See it in Fieldmotion

CRM1

In CRM1, open a job’s recurrence editor and use Save as Template; filter browser requests for Template_new or Template_setObj. The editor lists type 1 templates through Templates_get and removes job-specific values before saving. CRM2’s recurrence editor uses the same type-1 workflow.

CRM2

CRM2’s widgetTemplate.js loads Templates_get with JSON-encoded id/name/obj fields, parses obj locally, and uses Template_new, Template_setObj and Template_delete from its save/trash controls. Observe these requests in a create dialog whose configured layout includes the Template widget, such as a quote or invoice. The widget is layout-dependent, not present on every screen.

Related endpoints