Construction Industry Scheme Settings

Minimum access level: Full Access

A company can be registered as a contractor (it pays subcontractors and deducts tax on their behalf), as a subcontractor (it is paid under deduction), as both, or as neither.

This endpoint exposes the same settings as the CIS pages in the FreeAgent web app, for reading and writing. CIS only applies to UK limited companies and UK sole traders.

CIS settings are a singular resource - there is exactly one record per company, so there is no id in the URL and no index endpoint. PATCH is routed identically to PUT. There is no POST and no DELETE: to deregister, send null for a section.

Account manager tokens can operate on a specific client company by sending the client's subdomain in the X-Subdomain header, as for other company-level endpoints. See the Accountancy Practice API for details.

Attributes

The root object cis_settings always contains both of the following keys. null means the company is not registered in that capacity.

Attribute Description Kind
contractor_details The company's contractor registration, or null Object
subcontractor_details The company's subcontractor registration, or null Object

contractor_details

Attribute Description Kind
reporting_starts_on The date the company started reporting as a contractor. Required when registering as a contractor, and must be on or after 2016-04-06. Locked once CIS returns have been filed Date
paye_ni_period How often the company pays HMRC. One of Monthly or Quarterly. If omitted, the company's existing payroll setting is kept. Shared with payroll, so changing it here changes it for payroll too String

subcontractor_details

Attribute Description Kind
cis_deduction_rates The deduction rates that apply to the company. Locked for any rate already used on an invoice. See CIS bands. Array
prior_deductions CIS deductions suffered before the company started using FreeAgent, or null to clear the recorded values Object

prior_deductions

Prior deductions are CIS deductions the company suffered before it started using FreeAgent.

Attribute Description Kind
start_date The start of the tax year the opening balance relates to. Required whenever prior_deductions is given. Locked once the company is running RTI payroll in FreeAgent Date
initial_balance The opening balance, to 2 decimal places, e.g. "300.00". Required whenever prior_deductions is given, and must be greater than or equal to 0. Accepts a decimal string or a number on input. Locked once the company is running RTI payroll in FreeAgent Decimal

prior_deductions is null when the company has not recorded any. The key is absent entirely when the concept does not apply to the company at all - for sole traders, and for limited companies already running RTI payroll in FreeAgent with no prior deductions recorded.

Get CIS settings

GET https://api.freeagent.com/v2/cis_settings

Response

Status: 200 OK
{
  "cis_settings": {
    "contractor_details": {
      "reporting_starts_on": "2024-05-06",
      "paye_ni_period": "Monthly"
    },
    "subcontractor_details": {
      "cis_deduction_rates": ["cis_gross", "cis_standard", "cis_higher"],
      "prior_deductions": {
        "start_date": "2019-04-06",
        "initial_balance": "300.00"
      }
    }
  }
}
Show as XML
<?xml version="1.0" encoding="UTF-8"?>
<freeagent>
  <cis-settings>
    <contractor-details>
      <reporting-starts-on type="date">2024-05-06</reporting-starts-on>
      <paye-ni-period>Monthly</paye-ni-period>
    </contractor-details>
    <subcontractor-details>
      <cis-deduction-rates type="array">
        <cis-deduction-rate>cis_gross</cis-deduction-rate>
        <cis-deduction-rate>cis_standard</cis-deduction-rate>
        <cis-deduction-rate>cis_higher</cis-deduction-rate>
      </cis-deduction-rates>
      <prior-deductions>
        <start-date type="date">2019-04-06</start-date>
        <initial-balance type="decimal">300.00</initial-balance>
      </prior-deductions>
    </subcontractor-details>
  </cis-settings>
</freeagent>
Show as JSON

Update CIS settings

PUT https://api.freeagent.com/v2/cis_settings

Payload should have a root of cis_settings. A successful update returns 200 OK and the same object as GET.

contractor_details, subcontractor_details and prior_deductions each work the same way:

What you send What happens
Key omitted That section is left completely untouched
Key present, null Removes it - the company is deregistered in that capacity, or the recorded prior deductions are cleared
Key present, an object Registers the company (if not already registered) and applies the attributes given

Anything other than an object or null for those keys is rejected. So one section can be updated, or removed, without mentioning the other. The whole request is applied in a single transaction - if any part is rejected, nothing is written.

Registering as a contractor generates CIS returns for each tax month from reporting_starts_on.

Example request

Registers the company as a contractor and records prior deductions. The company's existing deduction rates are left alone.

{
  "cis_settings": {
    "contractor_details": {
      "reporting_starts_on": "2024-05-06",
      "paye_ni_period": "Quarterly"
    },
    "subcontractor_details": {
      "prior_deductions": {
        "start_date": "2019-04-06",
        "initial_balance": "300.00"
      }
    }
  }
}
Show as XML
<cis-settings>
  <contractor-details>
    <reporting-starts-on>2024-05-06</reporting-starts-on>
    <paye-ni-period>Quarterly</paye-ni-period>
  </contractor-details>
  <subcontractor-details>
    <prior-deductions>
      <start-date>2019-04-06</start-date>
      <initial-balance>300.00</initial-balance>
    </prior-deductions>
  </subcontractor-details>
</cis-settings>
Show as JSON

Example request to deregister

Deregisters the company as a contractor, leaving the subcontractor registration alone.

{
  "cis_settings": {
    "contractor_details": null
  }
}
Show as XML
<cis-settings>
  <contractor-details nil="true"/>
</cis-settings>
Show as JSON

Errors

Status When
400 The request was malformed - a missing root key, the wrong JSON type, an unknown enum value, or an attribute that does not apply to this company type
403 The token's permission level is insufficient, or CIS does not apply to this company type
422 The request was well-formed but the data was rejected - for example an attribute that is locked because it has already been used in the company's accounting, no deduction rates selected, or a deregistration that the company's records do not allow

Errors are returned in the standard FreeAgent format, with the attribute name prefixed into the message and dot-separated, matching the path in the request payload:

Status: 400 Bad Request
{
  "errors": [
    {
      "message": "contractor_details.paye_ni_period must be one of Monthly, Quarterly"
    }
  ]
}
Show as XML
<?xml version="1.0" encoding="UTF-8"?>
<freeagent>
  <errors>
    <error>
      <message>contractor_details.paye_ni_period must be one of Monthly, Quarterly</message>
    </error>
  </errors>
</freeagent>
Show as JSON