Remove controls from a project’s scope#
Description#
Remove up to 250 controls from a project’s scope, identified by scope-entry id (ScopedControl.id from the scoped-controls list, not the control’s own id). Removal is soft: removed controls stay visible in the scoped-controls list with a removedFromScope status. A rationale is required and recorded against every entry in the request as its scopeRationale; it is separate from the project-level scopingRationale. An entry that is not currently in scope is rejected. Returns the affected scoped controls. Supported only for Independent Controls Testing projects.
POST /assuranceProjects/{id}/scopedControls/removal
Required OAuth Scopes
grc:write
Parameters#
Parameter |
In |
Type |
Required |
Description |
|---|---|---|---|---|
X-Version |
header |
string |
true |
Version of the API (2026-09-01.grc.preview) |
body |
body |
true |
||
Wk-Workspace |
header |
string |
true |
The id of the Workiva workspace to operate in. Authorization is enforced against the authenticated user’s access within this workspace. |
id |
path |
string |
true |
The unique system identifier of the resource. |
Body parameter example#
{
"data": [
"019cb0a1-2f3e-7c22-9a10-4d5e6f7a8b90"
],
"rationale": "Below materiality threshold for FY26."
}
Code Samples#
curl -X POST 'https://api.app.wdesk.com/assuranceProjects/{id}/scopedControls/removal' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Wk-Workspace: 1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d' \
-H 'Authorization: Bearer {access-token}' \
-H 'X-Version: 2026-09-01.grc.preview' \
--data-raw '{"data":["019cb0a1-2f3e-7c22-9a10-4d5e6f7a8b90"],"rationale":"Below materiality threshold for FY26."}'
echo '{"data":["019cb0a1-2f3e-7c22-9a10-4d5e6f7a8b90"],"rationale":"Below materiality threshold for FY26."}' | http POST https://api.app.wdesk.com/assuranceProjects/{id}/scopedControls/removal \
X-Version:2026-09-01.grc.preview \
Content-Type:application/json \
Accept:application/json \
Wk-Workspace:1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d \
Authorization:"Bearer {access-token}"
wget --method=POST "https://api.app.wdesk.com/assuranceProjects/{id}/scopedControls/removal" \
--output-document - \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Wk-Workspace: 1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d' \
--header 'Authorization: Bearer {access-token}' \
--header 'X-Version: 2026-09-01.grc.preview' \
--body-data='{"data":["019cb0a1-2f3e-7c22-9a10-4d5e6f7a8b90"],"rationale":"Below materiality threshold for FY26."}'
import requests
headers = {
'X-Version': '2026-09-01.grc.preview',
'Content-Type': 'application/json',
'Accept': 'application/json',
'Wk-Workspace': '1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d',
'Authorization': 'Bearer {access-token}'
}
body = {
"data": [
"019cb0a1-2f3e-7c22-9a10-4d5e6f7a8b90"
],
"rationale": "Below materiality threshold for FY26."
}
r = requests.post('https://api.app.wdesk.com/assuranceProjects/{id}/scopedControls/removal', headers = headers, json=body)
print(r.json())
Returns#
200 - The controls now removed from scope.#
The scope entries affected by an add, remove, or re-add, with their resulting state. Added controls appear with their newly assigned ScopedControl.id and an inScope status; removed and re-added entries reflect their new status and rationale. Not paginated.
400 - The request was invalid.#
Error response indicating the service could not process the request.
401 - Authentication is missing or invalid.#
Error response indicating the service could not process the request.
403 - The caller is not permitted to access this resource.#
Error response indicating the service could not process the request.
404 - The requested resource was not found.#
Error response indicating the service could not process the request.
409 - The request conflicts with the state of the target resource, for example an operation attempted on an unsupported project type.#
Error response indicating the service could not process the request.
429 - The rate limit has been exceeded.#
Error response indicating the service could not process the request.
500 - An unexpected error occurred.#
Error response indicating the service could not process the request.
Example Responses#
{
"data": [
{
"control": {
"controlId": "COSO-C-001",
"id": "019cafc7-4901-7181-a53b-b2263115961d",
"name": "Code of Conduct and Ethics Policy"
},
"id": "019cb0a1-2f3e-7c22-9a10-4d5e6f7a8b90",
"scopeRationale": "Below materiality threshold for FY26.",
"scopeStatus": "removedFromScope"
}
]
}
{
"code": "invalidFilter",
"message": "The $filter value could not be parsed.",
"target": "$filter"
}
{
"code": "unauthenticated",
"message": "Authentication credentials were missing or invalid."
}
{
"code": "permissionDenied",
"message": "You do not have permission to access this resource."
}
{
"code": "notFound",
"message": "No resource with this id was found."
}
{
"code": "unsupportedProjectType",
"message": "This operation is only supported for Independent Controls Testing projects.",
"target": "/type"
}
{
"code": "rateLimitExceeded",
"message": "Rate limit exceeded. Retry after the period indicated in the response headers."
}
{
"code": "internalError",
"message": "An unexpected error occurred. Please try again later."
}