Update an issue#

Description#

Apply a JSON Patch (RFC 6902) to a remediation issue. Only the replace operation is supported. Include one operation per field you want to change, at most 100 operations; fields without an operation are left unchanged.

Options#

| Path | PATCH Operations Supported | Value Type | |———————————–|—————————-|————————————————————————————————-| | /name | replace | string | | /description | replace | string | | /rootCause | replace | string, null | | /supplementalInformation | replace | string, null | | /severity | replace | string: minor, moderate, high, unassigned | | /soxDeficiency | replace | string: notSet, deficiency, materialWeakness, significantDeficiency | | /auditTeamOwner | replace | User id string | | /businessOwner | replace | User id string, null | | /collaborators | replace | Array of user id string, at most 10 | | /controls | replace | Array of control id string, at most 5 | | /processes | replace | Array of process id string, at most 5 | | /risks | replace | Array of risk id string, at most 5 | | /targetRemediationDate | replace | Date string (YYYY-MM-DD), null | | /customFields/<custom field id> | replace | Object with exactly one of stringValue, dateValue, enumValue or enumValues; null | A null value clears the paths that list null above; the other paths do not accept null. Array values replace the whole list.

A custom field is patched by its custom field id, not by replacing the /customFields array. The value is an object with exactly one of stringValue, dateValue, enumValue, or enumValues, matching the field’s type. A null value clears that field. Other custom fields on the issue are left unchanged.

Status transitions are not supported via PATCH; attempting to patch /status returns 400.

PATCH /issues/{id}

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)

id

path

string

true

The unique system identifier of the resource.

body

body

JSONPatchDocument

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.

Body parameter example#

[
  {
    "op": "replace",
    "path": "/name",
    "value": "Updated issue name"
  },
  {
    "op": "replace",
    "path": "/severity",
    "value": "high"
  },
  {
    "op": "replace",
    "path": "/rootCause",
    "value": null
  },
  {
    "op": "replace",
    "path": "/customFields/8f3c1a2b-4d5e-4f6a-8b7c-9d0e1f2a3b4c",
    "value": {
      "enumValue": "High"
    }
  }
]

Code Samples#

curl -X PATCH 'https://api.app.wdesk.com/issues/{id}' \
    -H 'Content-Type: application/json-patch+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 '[{"op":"replace","path":"/name","value":"Updated issue name"},{"op":"replace","path":"/severity","value":"high"},{"op":"replace","path":"/rootCause","value":null},{"op":"replace","path":"/customFields/8f3c1a2b-4d5e-4f6a-8b7c-9d0e1f2a3b4c","value":{"enumValue":"High"}}]'
echo '[{"op":"replace","path":"/name","value":"Updated issue name"},{"op":"replace","path":"/severity","value":"high"},{"op":"replace","path":"/rootCause","value":null},{"op":"replace","path":"/customFields/8f3c1a2b-4d5e-4f6a-8b7c-9d0e1f2a3b4c","value":{"enumValue":"High"}}]' | http PATCH https://api.app.wdesk.com/issues/{id} \
    X-Version:2026-09-01.grc.preview \
    Content-Type:application/json-patch+json \
    Accept:application/json \
    Wk-Workspace:1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d \
    Authorization:"Bearer {access-token}"
wget --method=PATCH "https://api.app.wdesk.com/issues/{id}" \
    --output-document - \
    --header 'Content-Type: application/json-patch+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='[{"op":"replace","path":"/name","value":"Updated issue name"},{"op":"replace","path":"/severity","value":"high"},{"op":"replace","path":"/rootCause","value":null},{"op":"replace","path":"/customFields/8f3c1a2b-4d5e-4f6a-8b7c-9d0e1f2a3b4c","value":{"enumValue":"High"}}]'
import requests

headers = {
  'X-Version': '2026-09-01.grc.preview',
  'Content-Type': 'application/json-patch+json',
  'Accept': 'application/json',
  'Wk-Workspace': '1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d',
  'Authorization': 'Bearer {access-token}'
}

body = [
  {
    "op": "replace",
    "path": "/name",
    "value": "Updated issue name"
  },
  {
    "op": "replace",
    "path": "/severity",
    "value": "high"
  },
  {
    "op": "replace",
    "path": "/rootCause",
    "value": None
  },
  {
    "op": "replace",
    "path": "/customFields/8f3c1a2b-4d5e-4f6a-8b7c-9d0e1f2a3b4c",
    "value": {
      "enumValue": "High"
    }
  }
]

r = requests.patch('https://api.app.wdesk.com/issues/{id}', headers = headers, json=body)

print(r.json())

Returns#

200 - The updated issue.#

A remediation issue — a finding, deficiency, or action item tracked through resolution. Issues link to controls, processes, and risks via point-in-time snapshots that record the state of those entities when the issue was created; the snapshot data is returned as lightweight digests using the live entity identifiers where available.

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.

503 - Service Unavailable#

Error response indicating the service could not process the request.

Example Responses#

{
  "auditTeamOwner": {
    "id": "u_4cc9f9128a684f45a7a37b08b70b54c1"
  },
  "businessOwner": {
    "id": "u_9f8e7d6c5b4a43210f1e2d3c4b5a6978"
  },
  "collaborators": [
    {
      "id": "u_4cc9f9128a684f45a7a37b08b70b54c1"
    }
  ],
  "controls": [
    {
      "controlId": "BEN.001",
      "id": "d9c09501-214c-432e-85c9-8cd1009b9660",
      "name": "General Ledger Reconciliation"
    }
  ],
  "created": {
    "dateTime": "2026-03-15T14:30:00Z",
    "user": {
      "id": "u_4cc9f9128a684f45a7a37b08b70b54c1"
    }
  },
  "customFields": [
    {
      "enumValue": "High",
      "id": "8f3c1a2b-4d5e-4f6a-8b7c-9d0e1f2a3b4c",
      "name": "Risk Rating",
      "type": "singleSelectEnum"
    }
  ],
  "description": "The same individual can both create and approve purchase orders in the AP system without a secondary review.",
  "id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
  "isOverdue": false,
  "modified": {
    "dateTime": "2026-03-20T09:00:00Z",
    "user": {
      "id": "u_4cc9f9128a684f45a7a37b08b70b54c1"
    }
  },
  "name": "Segregation of duties violation in AP processing",
  "processes": [
    {
      "id": "2b1e5a7c-3d4f-4a1b-9c2d-6e7f8a9b0c1d",
      "name": "Financial Reporting"
    }
  ],
  "reportedDate": "2026-03-15",
  "risks": [],
  "rootCause": "Access controls not configured for dual-approval workflow.",
  "severity": "high",
  "soxDeficiency": "deficiency",
  "status": "open",
  "supplementalInformation": "Identified during Q3 walkthrough testing.",
  "targetRemediationDate": "2026-06-30",
  "type": "auditFinding"
}
{
  "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."
}
{
  "code": "503ServiceUnavailable",
  "message": "The server cannot handle the request due to a temporary overload or scheduled maintenance"
}