Skip to content

Update a site rate contract

PUT
/v1/clients/{clientId}/sites/{siteId}/rate-contracts/{id}
curl --request PUT \
--url https://api2.recruso.co.uk/v1/clients/1/sites/1/rate-contracts/1 \
--header 'Authorization: <Authorization>' \
--header 'Content-Type: application/json' \
--data '{ "jobDescription": "Order picking and pallet wrapping in a chilled environment.", "otRulesAndDetails": "Time and a half after 40 hours in a week.", "startTime": "2026-04-15T12:00:00Z", "endTime": "2026-04-15T12:00:00Z", "contactPersonId": 88, "healthAndSafety": "Chilled store, 2-4C. Manual handling briefing required.", "ppe": "Safety boots, hi-vis vest, thermal jacket.", "assessmentRequired": true, "assessmentDetails": "Manual handling assessment at the gatehouse.", "trainingRequired": true, "trainingDetails": "Half-day pallet truck training, renewed annually.", "inductionRequired": true, "inductionDetails": "Site induction on first shift, 45 minutes.", "holidayEntitlement": 28, "agriculture": true, "expensesPaid": "Mileage at 45p per mile beyond 25 miles.", "collectiveFacilities": "example", "permanentVacancyAccess": "example", "intervalOfPayments": "Weekly", "lengthOfTermination": "1 week", "frenchExtension": true, "dayRateRuleId": 2, "breakTime": "30 minutes unpaid", "restTimeBetweenShifts": 11, "natureOfBusiness": "example", "isRolledUpHoliday": false, "rolledUpHolidayOn": "2026-04-06T00:00:00", "holidayPolicy": "Accrued at 12.07% of hours worked.", "periodOfExtendedHire": "example", "ratesToAddOrUpdate": [ { "rateTypeId": 1, "prePayRate": 12.6, "preChargeRate": 16.8, "preRequiredForHolidayPot": true, "prePayRateLimited": 1, "prePayRatePsc": 1, "preMarginRate": 1, "preMarginRateLimited": 1, "preMarginRatePsc": 1, "preUseInAod": true, "postPayRate": 13.4, "postChargeRate": 17.65, "postRequiredForHolidayPot": true, "postPayRateLimited": 1, "postPayRatePsc": 1, "postMarginRate": 1, "postMarginRateLimited": 1, "postMarginRatePsc": 1, "postUseInAod": true } ], "rateTypeIdsToRemove": [ 1 ] }'

Updates one rate contract on one of your own agency’s sites.

The contract’s own fields are a full replacement — every mutable field is written from the request, so an omitted field is set to null.

The rates are not. Rates change by delta rather than by replacement: ratesToAddOrUpdate adds a rate pair for a rate type the contract does not have, or overwrites the pair it does, and rateTypeIdsToRemove drops pairs by rate type. Omitting both leaves every existing rate untouched. A rate type may appear only once in ratesToAddOrUpdate, and a rateTypeIdsToRemove entry the contract does not hold returns 400.

A contract must keep at least one rate pair. A request that would remove them all returns 400.

jobCategoryId, shiftId and isDailyRate are fixed at creation and are not part of this request. Where isDailyRate is true, dayRateRuleId must still be supplied and greater than 0.

As on create, a margin shortfall is a warning, not an error: the update succeeds and warnings names the pairs that fell below their rate type’s minimum.

The site must belong to the client named in the route and the contract to that site; otherwise 404.

Access. Requires a client-credentials access token. Tokens issued through the interactive user login are rejected.

clientId
required
integer format: int32

The clientId path parameter

siteId
required
integer format: int32

The siteId path parameter

id
required
integer format: int32

The id path parameter

Media typeapplication/json

The replacement values for a rate contract. The contract’s own fields are fully replaced, so an omitted field is set to null; its rates change by delta instead. Job category, shift and daily-rate mode are fixed at creation and are absent here.

object
jobDescription

The job description for work under this contract. Up to 5000 characters.

string
nullable
Example
Order picking and pallet wrapping in a chilled environment.
otRulesAndDetails

The overtime rules that apply, as free text. Up to 500 characters.

string
nullable
Example
Time and a half after 40 hours in a week.
startTime
string format: date-time
nullable
endTime
string format: date-time
nullable
contactPersonId

The site contact responsible for this contract. Must be a contact of the same site.

integer format: int32
nullable
Example
88
healthAndSafety

Health and safety information for work under this contract. Up to 5000 characters.

string
nullable
Example
Chilled store, 2-4C. Manual handling briefing required.
ppe

The personal protective equipment required for this work. Up to 5000 characters.

string
nullable
Example
Safety boots, hi-vis vest, thermal jacket.
assessmentRequired

Whether a worker must complete an assessment before being placed under this contract.

boolean
nullable
Example
true
assessmentDetails

What the required assessment involves. Up to 5000 characters.

string
nullable
Example
Manual handling assessment at the gatehouse.
trainingRequired

Whether a worker must complete training before being placed under this contract.

boolean
nullable
Example
true
trainingDetails

What the required training involves. Up to 5000 characters.

string
nullable
Example
Half-day pallet truck training, renewed annually.
inductionRequired

Whether a worker must complete an induction before being placed under this contract.

boolean
nullable
Example
true
inductionDetails

What the required induction involves. Up to 5000 characters.

string
nullable
Example
Site induction on first shift, 45 minutes.
holidayEntitlement

The holiday entitlement for work under this contract.

integer format: int32
nullable
Example
28
agriculture
boolean
nullable
expensesPaid

What expenses are paid under this contract. Up to 5000 characters.

string
nullable
Example
Mileage at 45p per mile beyond 25 miles.
collectiveFacilities
string
nullable
permanentVacancyAccess
string
nullable
intervalOfPayments

How often workers are paid under this contract. Up to 50 characters.

string
nullable
Example
Weekly
lengthOfTermination

The notice required to end an assignment under this contract. Up to 50 characters.

string
nullable
Example
1 week
frenchExtension
boolean
dayRateRuleId

The day rate rule that applies, as an id from your agency’s Day rate rules lookup. Required when isDailyRate is true.

integer format: int32
nullable
Example
2
breakTime

The break time for work under this contract, as free text. Up to 25 characters.

string
nullable
Example
30 minutes unpaid
restTimeBetweenShifts

The rest time required between consecutive shifts.

number format: double
nullable
Example
11
natureOfBusiness
string
nullable
isRolledUpHoliday

Whether holiday pay is rolled up into the rate rather than accrued.

boolean
nullable
Example
false
rolledUpHolidayOn

When rolled-up holiday pay was turned on for this contract, in UK local time (GMT/BST).

string format: date-time
nullable
Example
2026-04-06T00:00:00
holidayPolicy

The holiday policy that applies to this contract. Up to 4000 characters.

string
nullable
Example
Accrued at 12.07% of hours worked.
periodOfExtendedHire
string
nullable
ratesToAddOrUpdate

Rate pairs to add or update. If a RateTypeId already exists, it will be updated; otherwise, it will be added.

Array<object>
nullable

Represents a rate pair input (pre-parity and post-parity) for a specific rate type. Duration is handled internally and is not exposed to the API.

object
rateTypeId

The rate type ID (FK to tblRateTypes in AgencySettings).

integer format: int16
prePayRate

The hourly rate paid to the worker before they qualify for AWR parity.

number format: double
Example
12.6
preChargeRate

The hourly rate charged to the client before the worker qualifies for AWR parity.

number format: double
Example
16.8
preRequiredForHolidayPot

Whether the pre-parity rate contributes to the worker’s holiday pot.

boolean
Example
true
prePayRateLimited
number format: double
nullable
prePayRatePsc
number format: double
nullable
preMarginRate
number format: double
nullable
preMarginRateLimited
number format: double
nullable
preMarginRatePsc
number format: double
nullable
preUseInAod
boolean
nullable
postPayRate

The hourly rate paid to the worker once they qualify for AWR parity.

number format: double
Example
13.4
postChargeRate

The hourly rate charged to the client once the worker qualifies for AWR parity.

number format: double
Example
17.65
postRequiredForHolidayPot

Whether the post-parity rate contributes to the worker’s holiday pot.

boolean
Example
true
postPayRateLimited
number format: double
nullable
postPayRatePsc
number format: double
nullable
postMarginRate
number format: double
nullable
postMarginRateLimited
number format: double
nullable
postMarginRatePsc
number format: double
nullable
postUseInAod
boolean
nullable
rateTypeIdsToRemove

Rate type IDs to remove. Cannot remove all rates; at least one must remain.

Array<integer>
nullable

OK

Media typeapplication/json

A rate contract as it stands after the update, with any advisory margin warnings.

object
siteRateContractId

The rate contract’s unique identifier, assigned by Recruso.

integer format: int32
siteId

The site this rate contract applies to.

integer format: int32
jobCategoryId

The job category this contract prices, as an id from your agency’s Job categories lookup. Required, and fixed at creation.

integer format: int32
shiftId

The shift this contract prices, as an id from your agency’s Shifts lookup. Fixed at creation.

integer format: int32
nullable
jobDescription

The job description for work under this contract. Up to 5000 characters.

string
nullable
otRulesAndDetails

The overtime rules that apply, as free text. Up to 500 characters.

string
nullable
startTime
string format: date-time
nullable
endTime
string format: date-time
nullable
contactPersonId

The site contact responsible for this contract. Must be a contact of the same site.

integer format: int32
nullable
healthAndSafety

Health and safety information for work under this contract. Up to 5000 characters.

string
nullable
ppe

The personal protective equipment required for this work. Up to 5000 characters.

string
nullable
assessmentRequired

Whether a worker must complete an assessment before being placed under this contract.

boolean
nullable
assessmentDetails

What the required assessment involves. Up to 5000 characters.

string
nullable
trainingRequired

Whether a worker must complete training before being placed under this contract.

boolean
nullable
trainingDetails

What the required training involves. Up to 5000 characters.

string
nullable
inductionRequired

Whether a worker must complete an induction before being placed under this contract.

boolean
nullable
inductionDetails

What the required induction involves. Up to 5000 characters.

string
nullable
holidayEntitlement

The holiday entitlement for work under this contract.

integer format: int32
nullable
agriculture
boolean
nullable
expensesPaid

What expenses are paid under this contract. Up to 5000 characters.

string
nullable
collectiveFacilities
string
nullable
permanentVacancyAccess
string
nullable
intervalOfPayments

How often workers are paid under this contract. Up to 50 characters.

string
nullable
lengthOfTermination

The notice required to end an assignment under this contract. Up to 50 characters.

string
nullable
frenchExtension
boolean
modifiedOn

When the contract was last updated, in UK local time (GMT/BST) — not UTC. Null until the contract is first updated.

string format: date-time
nullable
isDeleted

Whether the contract is deleted. Deleted contracts are excluded from the list but are still returned when fetched by id.

boolean
nullable
isDailyRate

Whether the contract is priced at a daily rate rather than an hourly one. Fixed at creation, and requires dayRateRuleId when true.

boolean
nullable
createdBy

The Recruso user who created the contract.

integer format: int16
nullable
createdOn

When the contract was created, in UK local time (GMT/BST) — not UTC.

string format: date-time
nullable
modifiedBy

The Recruso user who last updated the contract. Null until the contract is first updated.

integer format: int16
nullable
dayRateRuleId

The day rate rule that applies, as an id from your agency’s Day rate rules lookup. Required when isDailyRate is true.

integer format: int32
nullable
breakTime

The break time for work under this contract, as free text. Up to 25 characters.

string
nullable
restTimeBetweenShifts

The rest time required between consecutive shifts.

number format: double
nullable
natureOfBusiness
string
nullable
isRolledUpHoliday

Whether holiday pay is rolled up into the rate rather than accrued.

boolean
nullable
rolledUpHolidayOn

When rolled-up holiday pay was turned on for this contract, in UK local time (GMT/BST).

string format: date-time
nullable
holidayPolicy

The holiday policy that applies to this contract. Up to 4000 characters.

string
nullable
periodOfExtendedHire
string
nullable
rates

The rate pairs associated with this contract. Each entry groups pre-parity and post-parity rates for a specific rate type.

Array<object>

API response DTO for a site rate pair in details view. Groups pre-parity (Duration=0) and post-parity (Duration=12) rates for a specific rate type. Duration is not exposed in the API.

object
siteRateId

The identifier of the pre-parity rate row in this pair.

integer format: int32
rateTypeId

The rate type this pair prices, as an id from your agency’s Rate types lookup.

integer format: int16
prePayRate

The hourly rate paid to the worker before they qualify for AWR parity.

number format: double
preChargeRate

The hourly rate charged to the client before the worker qualifies for AWR parity.

number format: double
preRequiredForHolidayPot

Whether the pre-parity rate contributes to the worker’s holiday pot.

boolean
prePayRateLimited
number format: double
nullable
prePayRatePsc
number format: double
nullable
preMarginRate
number format: double
nullable
preMarginRateLimited
number format: double
nullable
preMarginRatePsc
number format: double
nullable
preUseInAod
boolean
nullable
postSiteRateId

The identifier of the post-parity rate row in this pair.

integer format: int32
postPayRate

The hourly rate paid to the worker once they qualify for AWR parity.

number format: double
postChargeRate

The hourly rate charged to the client once the worker qualifies for AWR parity.

number format: double
postRequiredForHolidayPot

Whether the post-parity rate contributes to the worker’s holiday pot.

boolean
postPayRateLimited
number format: double
nullable
postPayRatePsc
number format: double
nullable
postMarginRate
number format: double
nullable
postMarginRateLimited
number format: double
nullable
postMarginRatePsc
number format: double
nullable
postUseInAod
boolean
nullable
warnings

Advisory warnings (e.g. margin rate below threshold). The record was saved successfully. Empty when there are no warnings.

Array<string>
Example
{
"siteRateContractId": 3041,
"siteId": 512,
"jobCategoryId": 17,
"shiftId": 5,
"jobDescription": "Order picking and pallet wrapping in a chilled environment.",
"otRulesAndDetails": "Time and a half after 40 hours in a week.",
"contactPersonId": 88,
"healthAndSafety": "Chilled store, 2-4C. Manual handling briefing required.",
"ppe": "Safety boots, hi-vis vest, thermal jacket.",
"assessmentRequired": true,
"assessmentDetails": "Manual handling assessment at the gatehouse.",
"trainingRequired": true,
"trainingDetails": "Half-day pallet truck training, renewed annually.",
"inductionRequired": true,
"inductionDetails": "Site induction on first shift, 45 minutes.",
"holidayEntitlement": 28,
"expensesPaid": "Mileage at 45p per mile beyond 25 miles.",
"intervalOfPayments": "Weekly",
"lengthOfTermination": "1 week",
"modifiedOn": "2026-06-11T14:02:09",
"isDeleted": false,
"isDailyRate": false,
"createdBy": 12,
"createdOn": "2026-03-12T15:33:20",
"modifiedBy": 12,
"dayRateRuleId": 2,
"breakTime": "30 minutes unpaid",
"restTimeBetweenShifts": 11,
"isRolledUpHoliday": false,
"rolledUpHolidayOn": "2026-04-06T00:00:00",
"holidayPolicy": "Accrued at 12.07% of hours worked.",
"rates": [
{
"siteRateId": 9107,
"rateTypeId": 3,
"prePayRate": 12.6,
"preChargeRate": 16.8,
"preRequiredForHolidayPot": true,
"postSiteRateId": 9108,
"postPayRate": 13.4,
"postChargeRate": 17.65,
"postRequiredForHolidayPot": true
}
]
}

Bad Request

Media typeapplication/problem+json
object
type
string
nullable
title
string
nullable
status
integer format: int32
nullable
detail
string
nullable
instance
string
nullable
Examplegenerated
{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example"
}

Unauthorized

Media typeapplication/problem+json
object
type
string
nullable
title
string
nullable
status
integer format: int32
nullable
detail
string
nullable
instance
string
nullable
Examplegenerated
{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example"
}

Forbidden

Media typeapplication/problem+json
object
type
string
nullable
title
string
nullable
status
integer format: int32
nullable
detail
string
nullable
instance
string
nullable
Examplegenerated
{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example"
}

Not Found

Media typeapplication/problem+json
object
type
string
nullable
title
string
nullable
status
integer format: int32
nullable
detail
string
nullable
instance
string
nullable
Examplegenerated
{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example"
}