Terminate a Contractor
Deactivating a contractor or other 1099 worker differs significantly from terminating a W-2 employee.
To "terminate" a contractor, you can schedule a dismissal or immediately mark a contractor as inactive.
The possible action depends on whether a contractor has received payments.
- Contractor has received payment: the contractor must be deactivated
- Contractor has not received payment: the contractor can be deleted
Using the contractor_management flow?If you are using the
contractor_managementflow, dismissals and rehires are handled automatically as part of the flow. You do not need to call the termination or rehire endpoints directly.
Schedule a contractor dismissal (recommended)
Schedule a contractor dismissal using the POST /v1/contractors/{contractor_uuid}/termination endpoint. This is the recommended approach for deactivating a contractor, as it allows you to specify a future end date and gives you the option to cancel before the date arrives.
The endpoint returns 204 No Content on success.
Sample request
curl --request POST \
--url https://api.gusto-demo.com/v1/contractors/{contractor_uuid}/termination \
--header 'accept: application/json' \
--header 'authorization: Bearer <<COMPANY_API_TOKEN>>' \
--header 'content-type: application/json' \
--data '
{
"end_date": "2025-06-15"
}
'const fetch = require('node-fetch');
const url = 'https://api.gusto-demo.com/v1/contractors/{contractor_uuid}/termination';
const options = {
method: 'POST',
headers: {
accept: 'application/json',
'content-type': 'application/json',
authorization: 'Bearer <<COMPANY_API_TOKEN>>'
},
body: JSON.stringify({
end_date: '2025-06-15'
})
};
fetch(url, options)
.then(res => res.json())
.then(json => console.log(json))
.catch(err => console.error('error:' + err));Cancel a scheduled dismissal
If you need to cancel a scheduled dismissal before the end date arrives, use the DELETE /v1/contractors/{contractor_uuid}/termination endpoint.
The endpoint returns 204 No Content on success.
Sample request
curl --request DELETE \
--url https://api.gusto-demo.com/v1/contractors/{contractor_uuid}/termination \
--header 'authorization: Bearer <<COMPANY_API_TOKEN>>'const fetch = require('node-fetch');
const url = 'https://api.gusto-demo.com/v1/contractors/{contractor_uuid}/termination';
const options = {
method: 'DELETE',
headers: {
authorization: 'Bearer <<COMPANY_API_TOKEN>>'
}
};
fetch(url, options)
.then(res => res.json())
.then(json => console.log(json))
.catch(err => console.error('error:' + err));Update the contractor status to inactive
You can also immediately mark a contractor as inactive using the PUT contractors/{contractor_uuid} endpoint and setting "is_active": false.
Conflict with scheduled transitionsIf the contractor already has a scheduled dismissal or a scheduled rehire, setting
is_activewill return a422 Unprocessable Entityerror. You must cancel the scheduled transition first before updatingis_activedirectly.
Sample request
curl --request PUT \
--url https://api.gusto-demo.com/v1/contractors/{contractor_uuid} \
--header 'accept: application/json' \
--header 'authorization: Bearer <<COMPANY_API_TOKEN>>' \
--header 'content-type: application/json' \
--data '
{
"type": "Individual",
"self_onboarding": false,
"file_new_hire_report": false,
"version": "b48c46abfed1487b873b442334b3c4ff",
"start_date": "2021-01-01",
"first_name": "Fanny",
"last_name": "Brice",
"middle_initial": "X",
"wage_type": "Hourly",
"hourly_rate": "20.00",
"is_active": false
}
'const fetch = require('node-fetch');
const url = 'https://api.gusto-demo.com/v1/contractors/{contractor_uuid}';
const options = {
method: 'PUT',
headers: {
accept: 'application/json',
'content-type': 'application/json',
authorization: 'Bearer <<COMPANY_API_TOKEN>>'
},
body: JSON.stringify({
type: 'Individual',
self_onboarding: false,
file_new_hire_report: false,
version: 'b48c46abfed1487b873b442334b3c4ff',
start_date: '2021-01-01',
first_name: 'Fanny',
last_name: 'Brice',
middle_initial: 'X',
wage_type: 'Hourly',
hourly_rate: '20.00',
is_active: false
})
};
fetch(url, options)
.then(res => res.json())
.then(json => console.log(json))
.catch(err => console.error('error:' + err));Rehire a contractor
If a contractor was previously dismissed, you can schedule a rehire using the POST /v1/contractors/{contractor_uuid}/rehire endpoint. Provide the start_date for when the contractor should become active again.
The endpoint returns 204 No Content on success.
Using the contractor_management flow?If you are using the
contractor_managementflow, rehires are handled automatically as part of the flow. You do not need to call the rehire endpoint directly.
Conflict with scheduled transitionsIf the contractor already has a scheduled rehire or a scheduled dismissal, this endpoint will return a
422 Unprocessable Entityerror. Similarly, settingis_activetotruevia the PUT endpoint will return a422if a scheduled rehire already exists. Cancel the existing scheduled transition first.
Sample request
curl --request POST \
--url https://api.gusto-demo.com/v1/contractors/{contractor_uuid}/rehire \
--header 'accept: application/json' \
--header 'authorization: Bearer <<COMPANY_API_TOKEN>>' \
--header 'content-type: application/json' \
--data '
{
"start_date": "2025-07-01"
}
'const fetch = require('node-fetch');
const url = 'https://api.gusto-demo.com/v1/contractors/{contractor_uuid}/rehire';
const options = {
method: 'POST',
headers: {
accept: 'application/json',
'content-type': 'application/json',
authorization: 'Bearer <<COMPANY_API_TOKEN>>'
},
body: JSON.stringify({
start_date: '2025-07-01'
})
};
fetch(url, options)
.then(res => res.json())
.then(json => console.log(json))
.catch(err => console.error('error:' + err));Cancel a scheduled rehire
If you need to cancel a scheduled rehire before the start date arrives, use the DELETE /v1/contractors/{contractor_uuid}/rehire endpoint.
The endpoint returns 204 No Content on success.
Sample request
curl --request DELETE \
--url https://api.gusto-demo.com/v1/contractors/{contractor_uuid}/rehire \
--header 'authorization: Bearer <<COMPANY_API_TOKEN>>'const fetch = require('node-fetch');
const url = 'https://api.gusto-demo.com/v1/contractors/{contractor_uuid}/rehire';
const options = {
method: 'DELETE',
headers: {
authorization: 'Bearer <<COMPANY_API_TOKEN>>'
}
};
fetch(url, options)
.then(res => res.json())
.then(json => console.log(json))
.catch(err => console.error('error:' + err));Delete the contractor
If a given contractor has not received any payments, then you can use the DELETE /v1/contractors/{contractor_uuid} endpoint to delete the contractor.
After setting the contractor's status to inactive, ensure there are no pending payments or outstanding invoices. Once all payments have been processed and no further action is required, you can safely delete the contractor record using the DELETE /v1/contractors/{contractor_uuid} endpoint.
Sample request
curl --request DELETE \
--url https://api.gusto-demo.com/v1/contractors/{contractor_uuid} \
--header 'X-Gusto-API-Version: {version}' \
--header 'authorization: Bearer COMPANY_API_TOKEN' \Updated 4 days ago