Forms
Set a form’s invoiceable flag
/a/Form_setIsInvoiceable
Change the flag used by job/invoice interfaces to decide whether the form supports invoicing.
When to use this endpoint
Change the flag used by job/invoice interfaces to decide whether the form supports invoicing. This is separate from a job contract’s invoice restrictions.
Use a form ID supplied by the Forms list. Read the current definition before making a narrowly scoped change; this endpoint does not save questions, report templates or existing job answers.
Authentication and permissions
Authenticate with signed API-key fields or a logged-in CRM session. The signed key acts as its associated tenant user.
Existing-definition settings writes require Forms Edit (pageForms_edit); client administrators pass the standard permission helper. Roleless/non-edit users fail closed. Temporary setup accounts retain their provisioned Forms Edit permission; the metadata marker alone does not grant that permission.
The account features2.disableFormEdits=1 setting blocks definition writes, except temporary setup users. Writes stay in the authenticated tenant; they do not modify an outsourced source definition.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | Integer-compatible form ID | Yes | Required and truthy before integer conversion. Missing/null/blank/zero gives the ID error; a truthy malformed value can convert to zero and then fail the row lookup. |
val | Scalar value | Yes | Non-null value for is_invoiceable. No trimming or allowed-value validation; zero and blank are accepted. Use 0 or 1 in ordinary clients. |
Example request
$result = FM_api('Form_setIsInvoiceable', [
'id' => '1042',
'val' => '0',
]);
Example response
{
"ok": 1,
"sql": "update user1088_forms set is_invoiceable=\"0\", last_edited=\"2026-11-02 14:30:00\" where id=1042"
}
A changed reply includes the executed SQL string, with the authenticated tenant prefix and server-generated timestamp. The example uses placeholder tenant 1088. A no-op omits sql.
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":"form edits are disabled for this account"} | Account disableFormEdits is 1 and the actor is not a temporary setup user. |
{"error":"no ID provided"} | The ID is absent or false-like. |
{"error":"no val provided"} | val is absent/null. |
{"error":"form does not exist"} | No row for the integer-converted ID, or the initial lookup fails. |
{"error":"permission denied"} | The actor lacks Forms Edit. Client administrators pass the standard permission helper; the temporary marker alone grants no access. |
{"error":"Unable to save form settings. Check the saved state before retrying."} | A read, primary write, history, undo or transaction acknowledgement failed; do not replay an uncertain save without refreshing. |
Legacy application errors may be returned with HTTP 200. Check the decoded response for error, not only the HTTP status.
Behaviour and edge cases
- Normal clients use 0/1. This flag neither creates invoices nor makes every linked job invoiceable; contract and finance restrictions are separate.
- Requires an existing local form, including an archived one. There is no form-type restriction, active/deleted filter, owner check or automatic migration of saved job answers.
- The supplied value is written as quoted text without a boolean/bitmask allowlist. Normal clients send the values described below; arbitrary non-null text is not validated by this handler. The database column’s conversion/range rules still apply.
- An unchanged value returns {"ok":1,"warning":"value already set"} before update, history or undo creation.
- On change, locks the existing row and saves the setting, last_edited, attributed history and an after-change undo snapshot in one checked tenant transaction. Nested callers retain their transaction through a savepoint. Failed data/history/undo operations roll back; uncertain commits are not automatically replayed.
- No direct mobile app/m-service caller for this RPC was found. Mobile form definitions are downloaded through m’s syncDownloads form channel rather than these CRM calls.
Side effects
- Updates forms.is_invoiceable and last_edited, invalidates forms cache, records attributed form/is_invoiceable, inserts a full after-change row snapshot into undos, and commits all three together. A no-op skips these effects. No email, job event or inventory transaction is invoked.
See it in Fieldmotion
CRM1
Open Forms and change the Invoices cell. Filter Network for Form_setIsInvoiceable; the caller sends val.
CRM2
Forms exposes the Invoices setting through its mapped editor. No direct Form_setIsInvoiceable caller was found; the standard editor uses Form_updateData/Form_updateField rather than this dedicated setter.
Related endpoints
Form_getreads the stored definition.Forms_getByIdretrieves selected raw columns in a batch.