GuidesAPI ReferenceChangelogAPI StatusAPI PolicyGusto Security
Guides
These docs are for v2024-04-01. Click to read the latest docs for v2026-02-01.

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_management flow, 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 transitions

If the contractor already has a scheduled dismissal or a scheduled rehire, setting is_active will return a 422 Unprocessable Entity error. You must cancel the scheduled transition first before updating is_active directly.

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_management flow, rehires are handled automatically as part of the flow. You do not need to call the rehire endpoint directly.

🚧

Conflict with scheduled transitions

If the contractor already has a scheduled rehire or a scheduled dismissal, this endpoint will return a 422 Unprocessable Entity error. Similarly, setting is_active to true via the PUT endpoint will return a 422 if 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' \