Skip to main content

Step 2 — Assistance contracts

Optional, but defines how hours are billed. A contract gives the customer an hours ceiling that interventions consume.

Hierarchy

entity-contract-group → commercial grouping
entity-contract-type → periodicity, renewable, service type
entity-contract → customer contract, with totalHours (ceiling)

Always create in that order: the contract validates that group and type already exist.

2.1 Contract group

POST /gateway/entity-contract-group
Content-Type: application/json
Authorization: Bearer {token}
{
"id": 1,
"description": "Annual retainers"
}

Required: id (numeric, user-defined, > 0) and description (≤50 chars).
Next free number: GET /gateway/entity-contract-group/next-id.

2.2 Contract type

POST /gateway/entity-contract-type
Content-Type: application/json
Authorization: Bearer {token}
{
"id": 1,
"description": "Monthly time-based retainer",
"renewable": true,
"periodicity": 1,
"contractType": 2
}

Required: id (> 0), description (≤50 chars), periodicity and contractType. Optional: renewable.

FieldValues
periodicity1 = Monthly, 2 = Annual
contractType1 = Per service (PerService), 2 = Per time (PerTime)
Per-service vs per-time

contractType decides whether the hours ceiling matters: per-service contracts do not validate hours; only per-time contracts consume the ceiling. The hours-available endpoint returns this so integrators can skip validation when applicable.

2.3 Customer contract

POST /gateway/entity-contract
Content-Type: application/json
Authorization: Bearer {token}
{
"id": 1,
"entityKeyId": "C0001",
"contractGroupId": 1,
"contractTypeId": 1,
"startDate": "2026-01-01T00:00:00Z",
"endDate": "2026-12-31T00:00:00Z",
"totalHours": 40,
"contractValue": 1200.00,
"contractValueRp": 1200.00,
"contractCostValue": 800.00,
"observation": "Preventive maintenance retainer, 40h/year.",
"canceled": false
}

Required: id (> 0), entityKeyId (≤25 chars, customer must exist), contractGroupId, contractTypeId, startDate and endDate (end cannot be before start — InvalidDateRange).

Useful optional fields: totalHours, contractValue, contractValueRp, contractCostValue, observation (≤4000 chars), covenantId (≤50 chars; if sent, the agreement must exist) and canceled.

Next free number: GET /gateway/entity-contract/next-id.

Relevant endpoints

EndpointPurpose
GET /gateway/entity-contract?page=&pageSize=Paginated list
GET /gateway/entity-contract/{id}Detail
GET /gateway/entity-contract/{id}/hours-availableHours still available (totalHours, availableHours, contractType)
GET /gateway/entity-contract/{id}/has-documentsCheck dependencies before delete
GET /gateway/entity-contract/next-idNext free number
GET /gateway/intervention/by-contract/{contractId}Interventions charged to the contract
Deleting contracts in use

Deleting a contract with linked orders or interventions returns InUse. Check with has-documents first.

How the ceiling is consumed

The intervention links to the contract via entityContractId and discountTime (hours) is debited. When those hours are actually invoiced, a document reference of type ServiceOrderInterventionHours pointing at the intervention is created — invoiced hours free ceiling again, because they moved from contract consumption to a sale.

Available hours = totalHours - (hours used - hours already invoiced).

Next

Register equipment.