When to use this endpoint

Use the job report email dialog after reviewing the job and recipients. Unlike Job_getAsPdf, this asks the mail service to prepare/send documents; it does not return report bytes.

Authentication and permissions

Requires signed API-key or CRM-session authentication and an active job in the authenticated tenant. Report-only sending has no extra role guard, but crm_access bit 64 blocks invoice attachment through either attachment bit 1 or jobAttachments invoiceReport.

The dispatcher also applies user/account and IP restrictions. CRM sessions carrying a CSRF token must supply X-FMCSRF or _csrf; missing or incorrect tokens can be rejected before the handler runs.

Parameters

ParameterTypeRequiredDescription
idInteger stringYesPositive active physical job ID.
emailsStringNoIf present, overrides defaults even when blank. Commas become newlines; entries are trimmed and PHP-valid email addresses retained. Omitted: use customer email plus newline-separated customer meta.email_extra; asset jobs use the asset owner.
attachmentInteger stringNoDefault 0. Bit 1 requests the linked invoice as well as the job report. Other bits are ignored here.
jobAttachmentsNative arrayNoNonempty list overrides the mail service’s document/file selection: jobReport, invoiceReport, quoteReport, jobFiles, quoteFiles. Must arrive as an array (for example form fields jobAttachments[]); a JSON string is ignored by this handler. Unknown entries are not rejected.
messageStringNoOptional mail body, default empty; body is not the accepted request name.
template_idInteger stringNoDefault 0 lets the mail service resolve the form’s email template. A nonzero selection is forwarded.
subjectStringNoOptional subject override, default empty.

Example request

$result = FM_api('Job_emailReport', [
	'id' => '1042',
	'emails' => 'engineer@example.com, office@example.com',
	'attachment' => '0',
	'template_id' => '0',
	'subject' => 'Completed inspection',
	'message' => 'Please find the job report.',
]);

Example response

{"ok":1,"mail_id":0}

mail_id is the mail service’s local_id when returned, otherwise numeric 0. A zero ID is a real possible success-shaped response, not proof that nothing was sent.

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"}Missing/nonpositive id.
{"error":"Job not found!"}Job missing/deleted.
{"error":"no email address"}No address survived parsing/validation; explicitly blank emails does not fall back to the customer.
{"error":"Job email queue response was not confirmed. Check mail history before retrying."}Mail failed or returned an ambiguous acknowledgement. Earlier recipients may already be queued; do not repeat automatically.

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

Behaviour and edge cases

  • Valid addresses are not deduplicated and have no handler-side maximum. Customer/asset lookup rows are not active-filtered. No completion requirement applies, but crm_access bit 64 blocks invoice attachment via attachment bit 1 or jobAttachments invoiceReport before mail.
  • The mail service prepares job-report links/documents and uploaded job files by default. A nonempty jobAttachments list selects the named groups, but attachment bit 1 still separately controls CRM-side invoice-sent propagation. Selecting invoiceReport alone is not equivalent to setting that bit.
  • When attachment bit 1 is set, CRM selects the newest type-3 relation by relation ID, with no active-invoice join, then falls back to the newest active legacy-linked invoice. The mail service’s separate link lookup is unordered; inconsistent multiple links can select different invoices.
  • Sets job meta.report_sent after the mail call even if its reply is missing, invalid or an error. Does not set pdf_sent here; CRM1’s jobMail workflow calls Job_setPdfSent separately.
  • No list filters or pagination apply. The renderer/template and mail-service configuration govern document delivery; ok is not an SMTP-delivery receipt.

Side effects

  • Calls type-1 Core_mail, which can generate share links, documents and mail history.
  • Updates job report_sent, last_edited and edited_uuid=Job_emailReport and invalidates the meetings cache.
  • With attachment bit 1: writes invoice.email_sent and propagates invoice_sent to its directly linked jobs (legacy link only when no direct links), or marks this job invoice_sent if no invoice is found. These writes are not transactional with mail.

See it in Fieldmotion

CRM1

Open a job’s Send email dialog, Report tab, choose recipients/template/attachments and send. jobMail.js posts Job_emailReport then Job_setPdfSent; widgetSendEmail.js also calls this route. Filter both requests.

CRM2

Open the job email widget, select report/documents/files and send. widgetSendEmail.js posts Job_emailReport with native jobAttachments selections; inspect the submitted array and attachment flag separately.

Related endpoints