Contracts
Full CRUD on contracts, the agreements behind recurring spend: leases, licenses, service and framework agreements, supplier contracts. Requires the contracts feature for the company on every operation; without it the whole route answers 403.
Money fields
A contract carries five money amounts, contractPrice, netAmount, grossAmount, additionalCostNetAmount, totalLicenseAmount, each with a read-only …Currency sibling reporting the company currency. totalLicenseAmount is server-computed (licenseAmount × netAmount + additionalCostNetAmount) and overwritten on every save, so sending it has no lasting effect. totalContractPrice is read-only: the contract price times the recurrence's payment iterations.
Notice period and cancellation date
noticePeriod is {"type": "days" | "weeks" | "months" | "years", "count": n}. When startDate, endDate and noticePeriod are all set, the server computes cancellationDate as endDate - noticePeriod - reminderTime days, overwriting any value you sent.
Files
Contract documents render read-only as {id, title, fileExtension, url}. The url is presigned and lives 10 minutes, fetch it, use it, and re-read the contract for a fresh one; never store it. There is no file upload on this route.
What DELETE does
Soft delete, as everywhere on this tree, and contracts carry the tree's biggest delete side effect: every catalogue item linked to the contract is deactivated, and for a supplier-type contract the linked supplier is deactivated too. Undeleting the contract restores neither.
Relations
owner must be an active member of the URL company; department, category and companySupplier must belong to it. recurrence is a nested object (create or update it inline with the contract); it has no cross-company identity.
Operations
Reads need master-data:read, writes master-data:write.
- GET
/api/v2/{companyId}/contracts/: newest first by default. Narrow with?status=and?contractType=(words, repeated keys and comma lists accepted, unknown values400; no filter means no narrowing). - POST
/api/v2/{companyId}/contracts/:nameis required, everything else optional. - GET
/api/v2/{companyId}/contracts/{id}/: one contract. Soft-deleted rows are returned here too. - PUT / PATCH
/api/v2/{companyId}/contracts/{id}/: replace / partial update. - DELETE
/api/v2/{companyId}/contracts/{id}/: soft delete, with the deactivation side effects above.
Endpoints
/api/v2/{companyId}/contracts/?page=1&pageSize=25&status=pending&contractType=unit&orderin...
/api/v2/{companyId}/contracts/
/api/v2/{companyId}/contracts/{id}/
/api/v2/{companyId}/contracts/{id}/
/api/v2/{companyId}/contracts/{id}/
/api/v2/{companyId}/contracts/{id}/