Contracts
Replace legacy contract fields
/a/Contract_edit
Replace the CRM1 contract edit fields in one legacy save, including a complete rewrite of contract metadata.
When to use this endpoint
Use Contract_edit only to reproduce CRM1’s full edit dialog or the legacy CSV importer. It is replacement-oriented: omitted fields are written as blank or zero.
For targeted changes, use the relevant Contract_set* route or the mapped Contract_updateData endpoint.
Authentication and permissions
The request must authenticate as a nonzero user through signed API-key fields or a logged-in CRM session. The handler returns not logged in when no user ID is present.
No page or role-permission check is performed; the update uses the authenticated tenant.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | Integer string | Yes | Positive contract ID. Existence is checked without excluding soft-deleted rows. |
name | String | Effectively yes | Replacement name. The handler reads it without an existence or length check; omission can become an empty value after a runtime notice. |
type_id | Integer string | No | Replacement contract-type ID; defaults to 0 and is not validated. |
number / address / manager / notes | Strings | No | Replacement values; each defaults to blank. No schema-length validation is performed. |
budget | Number string | No | Converted with floatval; omitted and nonnumeric values become zero. |
not_invoiceable | Scalar | No | Stored as the only property in a newly encoded meta object; defaults to numeric 0. |
date_started | Date/time string | No | Applied only when strtotime produces an epoch after 2010-01-01; stored as YYYY-MM-DD. Blank/invalid values leave the old date unchanged. |
date_completed | Date/time string | No | Applied only when parsed after 2010-01-01; stored as a date-time. It cannot be cleared through this route. |
expiry | YYYY-MM-DD string | No | Legacy input. Shape is checked, but the handler writes a column named expiry rather than the mapped expiry_date and does not check the update result. Use Contract_setExpiryDate. |
Example request
$result = FM_api('Contract_edit', [
'id' => '720',
'name' => 'North Region Service Contract',
'type_id' => '8',
'number' => 'CT-720',
'address' => 'North Region',
'manager' => 'Service Desk',
'budget' => '25000',
'notes' => 'Renewal review due in September.',
'not_invoiceable' => '0',
]);
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":"not logged in"} | No authenticated user ID is available. |
{"error":"missing or invalid parameter: id"} | The ID is absent or not positive. |
{"error":"invalid parameter: expiry"} | A nonblank legacy expiry value does not match YYYY-MM-DD. |
{"error":"Contract does not exist"} | No contract row, including deleted rows, has the supplied ID. |
Legacy application errors may be returned with HTTP 200. Check the decoded response for error, not only the HTTP status.
Behaviour and edge cases
- This is a full legacy replacement, not a patch. Missing optional strings become blank and missing numeric values become zero.
- The endpoint can update a soft-deleted contract and always returns
okafter issuing the update, even if the database write fails. - When the
expirykey is present, the type-104 status worker is replaced using that value; contract email schedules are not synchronized.
Side effects
- Updates
last_editedand invalidates the contracts cache. - No contract audit entry, mention notice, or notification-service event is generated by this route.
See it in Fieldmotion
CRM1
Open Contracts, choose Edit on a row, save the dialog, and filter Network requests for Contract_edit. CRM1 sends all replacement fields together.
CRM2
No normal CRM2 caller was found. CRM2 uses mapped Contract_updateData and dedicated delete actions.
Related endpoints
Contract_updateDataperforms mapped partial updates and preserves unrelated metadata.Contract_setExpiryDateis the supported expiry mutation.Contract_getreads the stored legacy shape.