Quotes: queries, documents and delivery
Email a quote and selected attachments
/a/Quote_sendEmail
Submit a quote email to the mail service and mark the quote as emailed.
When to use this endpoint
Use after a user selects valid recipient addresses, subject and attachment options. An ok response is not proof of mail delivery.
Authentication and permissions
Authenticate with signed API-key fields or a CRM session. Requires Quotes View (pageQuotes_view); non-admin users blocked by legacy crm_access bit 32 are denied. Client administrators inherit page permissions.
Requires Quotes Edit in addition to View. Template setters also require client-administrator permission.
Quote visibility follows the account’s department/account-manager customer filters for non-admin users, including signed keys. Export routes additionally require pageMain_exportTableData. Linked Jobs require Jobs View and their TeamAccess scope; invoice enrichment requires Invoices View and the legacy invoice access check.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | Positive integer-compatible quote ID | Yes | Requires an active visible quote before the first mail call. |
emails | Newline-separated string | Yes, at least one valid address | Newline-separated valid addresses are trimmed and deduplicated; invalid lines are discarded. |
subject | String | Yes | Trimmed; empty fails. |
message | String | No | Trimmed body; defaults to empty. |
email_template | Integer-compatible template ID | No | Defaults to 0. Nonzero ID must be an unarchived general/type-Quote template in this tenant. |
file_attachments | Integer-compatible legacy mode | No | Defaults 0: quote report and files; 1: report; 2: files; other values select neither in the legacy mail path. Used when quoteAttachments is absent. |
quoteAttachments | Native array of attachment tokens | No | Native token list. Empty means no attachments; tokens and linked target permissions are checked before sending. |
Example request
$result = FM_api('Quote_sendEmail', [
'id'=>'1042',
'emails'=>"developer@example.com\naccounts@example.com",
'subject'=>'Quote QT-1042',
'message'=>'Please review the attached quote.',
'quoteAttachments'=>['quoteReport'],
]);
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"} | Missing/nonpositive ID. |
{"error":"no email address"} | No valid newline-separated recipients. |
{"error":"missing parameter: subject"} | Missing/blank subject. |
{"error":"no such quote"} | Active quote lookup after mail fails. |
{"error":"permission denied"} | Required Quotes/Export permission is absent or legacy access restrictions apply. |
Legacy application errors may be returned with HTTP 200. Check the decoded response for error, not only the HTTP status.
Behaviour and edge cases
- Requires Quotes Edit as well as View, an active visible quote and valid metadata before contacting the mail service. It cannot run while the caller has an open database transaction.
- Trims/validates newline-separated recipients and removes duplicates. Subject must be nonblank; message is trimmed. Nonzero templates must exist, be unarchived and be general/type-Quote templates.
- Attachment tokens are allowlisted. Job/invoice attachments must be active, linked to this quote and permitted to the user; file attachments also require Files View. Empty quoteAttachments explicitly means no attachments. Legacy file_attachments modes still choose the initial default tokens when the list is omitted.
- Requires mail ok=1 and a positive queue ID. Transport/error/uncertain acknowledgements return retry_safe=false and leave email_sent unchanged. Check mail history before trying another send; no automatic replay occurs.
- After a confirmed submission, locks and reloads current metadata, merges email_sent=1 and saves it with last_edited/history. Concurrent metadata survives. A post-send save failure returns ok=1/saved=1 with a warning and retry_safe=false so the UI must not resend.
- No distributed transaction can atomically commit mail and SQL. The endpoint does not change quote status; a UI status update is separate.
- No direct caller for this endpoint was found in the mobile app or its m-service intermediary.
Side effects
- External mail submission followed by a checked merge of email_sent, last_edited and history only after acknowledgement. A post-send SQL failure is reported as a no-resend warning.
See it in Fieldmotion
CRM1
Quotes/Customer Quotes → Email and shared email dialogs call Quote_sendEmail. Inspect emails as newline-separated text and legacy attachment mode.
CRM2
Quotes → Send Email uses widgetSendEmail with quoteAttachments; choosing none sends the noAttachments sentinel. Optional status changes are separate requests.
Related endpoints
Quote_getPdfpreviews the generated quote document.Quote_signatureRequestsends a signing-link request instead.