Contracts
Get contracts by ID
/a/Contracts_getById
Fetch selected contract records for an explicit ID batch, optionally limiting stored fields and adding linked job IDs.
When to use this endpoint
Use Contracts_getById after another call has produced a manageable list of contract IDs, especially in CRM1/CRM2 export expansion.
For one active contract with type and invoiceability helpers, use Contract_get.
Authentication and permissions
The request must establish an authenticated tenant context through signed API-key fields or a CRM session. The handler checks DBP and releases the PHP session lock before querying.
No page/role check or deleted-row filter is applied.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
ids | JSON array string or native array | Yes | IDs are integer-converted and deduplicated in first-seen order. The decoded input must be iterable and contain at least one value after conversion. |
fields | JSON array string | No | Selected stored field names. meta and id are always added. Unknown fields are ignored. Exact appointments requests linked job IDs instead of a database column. A native request array is not decoded by this handler. |
Example request
$rows = FM_api('Contracts_getById', [
'ids' => json_encode([720, 721]),
'fields' => json_encode(['id', 'name', 'budget', 'expiry_date', 'appointments']),
]);
Example response
[
{
"meta": "{\"stage\":\"renewal\"}",
"id": "720",
"name": "North Region Service Contract",
"budget": "25000",
"expiry_date": "2027-09-30",
"appointments": "[2039001]"
}
]
The exact legacy response key appointments contains a JSON-encoded array. Other database values remain strings/null.
Allowed stored fields are id, name, notes, active, budget, expiry_date, number, address, manager, custom, cdate, customers, last_edited, created_by, type_id, date_completed, and meta.
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: ids"} | The ids key is omitted. |
{"error":"no ids in list"} | A valid iterable contains no values. |
Server error/runtime warning | Malformed JSON for ids/fields produces a non-iterable value that the legacy loops do not validate. |
[] | No tenant row matches the converted IDs. |
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 query does not filter
deleted; explicitly supplied soft-deleted IDs can be returned. - When jobs are requested, it first selects non-deleted jobs whose direct
contract_idmatches. It falls back to type-6 links only if that direct list is empty, so the two sources are not unioned. - SQL does not establish result order, and missing IDs are omitted rather than represented by placeholders.
See it in Fieldmotion
CRM1
CRM1’s export widget uses Contracts_getById when expanding selected contract references into display fields. Filter Network requests during a mapped export containing contract values.
CRM2
CRM2’s export widgets also call this route with fields such as ID, name, notes, active, budget, expiry, number, address, and manager.
Related endpoints
Contract_getrepairs dirty customer cache and excludes deleted contracts.Contracts_getExportDatareturns positional export fields for explicit batches.Contract_getRequestedDetailsuses mapped camel-case field names.