> ## Documentation Index > Fetch the complete documentation index at: https://apidocs.document360.com/llms.txt > Use this file to discover all available pages before exploring further. # Update an article feedback record > Updates the status and/or the assignee of a feedback record. Send only the fields to change; the rest of the record is left as it is; a field sent as `null` counts as not sent. The body must contain at least one of `status` or `assignee_id`. **Closing:** `status: closed` closes the feedback, the same as closing it in the Portal. Add `close.comment` to record a resolution note and `close.notify_reader: true` to email the reader; the email is sent only if the reader opted in to updates when they left the feedback. `close` is accepted only together with `status: closed`. **Closed feedback cannot be changed here:** any change to it, including closing it again or setting it back to `open`, is refused with `409` and error code `FEEDBACK_CLOSED`, so retrying a close never emails the reader twice. A closed feedback can be reopened only in the Document360 portal; once reopened, it can be updated here again. **Retries:** sending a status or assignee the record already has changes nothing and returns `200`, so a status or assignee update is safe to retry. When both fields are sent, both are validated before either is written; the assignee is then applied before the status. If someone else closes the feedback between those two writes, the response is `409 FEEDBACK_CLOSED` although the assignee change was already saved; read the record to see its state. Every change is recorded in the feedback's history against the acting user. **Acting user:** with an API key, or an M2M token without the `X-Acting-User-Id` header, send `user_id`; the change is recorded against that user, who must belong to the project and have the `UpdateFeedbackManager` permission (else `403`), as well as the caller. **Body rules:** field names are case-sensitive snake_case: `Status`, `USER_ID` or `userId` is refused with `422 UNRECOGNIZED_FIELDS`. The `status` value is matched case-insensitively (`inProgress` and `InProgress` are the same) but must be a name, not a number. A property sent twice, or one this request does not define (such as the read-only `reader_comment` or `created_at`), is refused with `422`. A body that is not valid JSON, including one with a trailing comma, is refused with `400`. **Close comment:** plain text. It is sanitised when it is stored: HTML markup such as `", "examples": { "Change status and assignee": { "summary": "Moves the feedback to in progress and assigns it. `user_id` is needed only with an API key or an M2M token without `X-Acting-User-Id`.", "value": { "status": "inProgress", "assignee_id": "2b1a0f9e-8d7c-4b6a-9f5e-4d3c2b1a0f9e", "close": null, "user_id": "7c1e4d90-2a3b-4c5d-8e9f-0a1b2c3d4e5f" } }, "Close and notify the reader": { "summary": "Closes the feedback with a resolution note and emails the reader, if they opted in to updates. A closed feedback can no longer be modified.", "value": { "status": "closed", "assignee_id": null, "close": { "comment": "Resolved via Jira DOC-123. Updated the setup steps.", "notify_reader": true }, "user_id": "7c1e4d90-2a3b-4c5d-8e9f-0a1b2c3d4e5f" } }, "Close without a note": { "summary": "Closes the feedback without a resolution note and without emailing the reader.", "value": { "status": "closed", "assignee_id": null, "close": null, "user_id": "7c1e4d90-2a3b-4c5d-8e9f-0a1b2c3d4e5f" } } } } } }, "responses": { "200": { "description": "Feedback updated successfully.", "headers": { "X-RateLimit-Limit": { "description": "The maximum number of requests allowed in the current time window for this request's bucket. Read requests (GET/HEAD) and write requests (POST/PUT/PATCH/DELETE) have independent limits, applied per caller (API key or user) per project.", "schema": { "type": "integer", "format": "int32" } }, "X-RateLimit-Remaining": { "description": "The number of requests remaining in the current time window. When this reaches 0, subsequent requests receive a 429 response.", "schema": { "type": "integer", "format": "int32" } } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FeedbackDetailResponseApiResponse" }, "examples": { "Status and assignee changed": { "summary": "The record after the `Change status and assignee` request: `status` is `inProgress` and `assignee_id` is the new assignee.", "value": { "data": { "feedback_id": "66f1a2b3-c4d5-4e6f-a7b8-c9d0e1f2a3b4", "article_id": "9a3b4c5d-6e7f-4a9b-8c1d-2e3f4a5b6c7d", "article_title": "Getting started", "article_url": "https://docs.example.com/docs/en/getting-started", "workspace_id": "4d3c2b1a-0f9e-4d8c-b7a6-5f4e3d2c1b0a", "lang_code": "en", "feedback_type": "dislike", "is_page_category": false, "feedback_reasons": [ "inaccurate_or_irrelevant", "missing_or_broken_link" ], "reader_comment": "The setup steps are out of date.", "status": "inProgress", "assignee_id": "2b1a0f9e-8d7c-4b6a-9f5e-4d3c2b1a0f9e", "created_at": "2026-10-10T08:15:00Z", "updated_at": "2026-10-12T10:30:00Z", "discussion_count": 2 }, "success": true, "request_id": "0HN7A2K3L4M5N:00000004", "errors": null, "warnings": null } }, "Feedback closed": { "summary": "The record after a close request, with the same fields as `GET /{feedback_id}`: `status` is `closed` and `updated_at` is the close time.", "value": { "data": { "feedback_id": "66f1a2b3-c4d5-4e6f-a7b8-c9d0e1f2a3b4", "article_id": "9a3b4c5d-6e7f-4a9b-8c1d-2e3f4a5b6c7d", "article_title": "Getting started", "article_url": "https://docs.example.com/docs/en/getting-started", "workspace_id": "4d3c2b1a-0f9e-4d8c-b7a6-5f4e3d2c1b0a", "lang_code": "en", "feedback_type": "dislike", "is_page_category": false, "feedback_reasons": [ "inaccurate_or_irrelevant", "missing_or_broken_link" ], "reader_comment": "The setup steps are out of date.", "status": "closed", "assignee_id": "2b1a0f9e-8d7c-4b6a-9f5e-4d3c2b1a0f9e", "created_at": "2026-10-10T08:15:00Z", "updated_at": "2026-10-15T09:20:00Z", "discussion_count": 2 }, "success": true, "request_id": "0HN7A2K3L4M5N:00000005", "errors": null, "warnings": null } } } } } }, "400": { "description": "The request body is not valid JSON (error code `BAD_REQUEST`).", "content": { "application/problem+json": { "schema": { "allOf": [ { "$ref": "#/components/schemas/V3ProblemDetails" }, { "type": "object", "properties": { "type": { "enum": [ "https://apidocs.document360.io/apidocs/errors/bad-request" ], "type": "string", "description": "RFC 7807 error type URI. Always `https://apidocs.document360.io/apidocs/errors/bad-request` for 400 responses." }, "status": { "enum": [ 400 ], "type": "integer", "description": "HTTP status code. Always `400` for this response.", "format": "int32" } } } ] }, "examples": { "Malformed request body": { "summary": "The request body could not be parsed.", "value": { "type": "https://apidocs.document360.io/apidocs/errors/bad-request", "title": "Bad Request.", "status": 400, "detail": "The request body is malformed or contains invalid JSON.", "instance": null, "trace_id": "req_abc123def456", "errors": [ { "code": "BAD_REQUEST", "message": "Could not parse the request body. Ensure it is valid JSON.", "field": null, "details": null } ], "warnings": null } } } } } }, "401": { "description": "Authentication token is missing or invalid.", "headers": { "WWW-Authenticate": { "description": "Indicates the authentication scheme required. Returns `Bearer` with optional `error` and `error_description` parameters per RFC 6750.", "schema": { "type": "string" } } }, "content": { "application/problem+json": { "schema": { "allOf": [ { "$ref": "#/components/schemas/V3ProblemDetails" }, { "type": "object", "properties": { "type": { "enum": [ "https://apidocs.document360.io/apidocs/errors/unauthorized" ], "type": "string", "description": "RFC 7807 error type URI. Always `https://apidocs.document360.io/apidocs/errors/unauthorized` for 401 responses." }, "status": { "enum": [ 401 ], "type": "integer", "description": "HTTP status code. Always `401` for this response.", "format": "int32" } } } ] }, "examples": { "Missing or invalid token": { "summary": "Authentication token is missing or invalid.", "value": { "type": "https://apidocs.document360.io/apidocs/errors/unauthorized", "title": "Unauthorized.", "status": 401, "detail": "The authentication token is missing or has expired.", "instance": null, "trace_id": "req_abc123def456", "errors": [ { "code": "UNAUTHORIZED", "message": "Bearer token is missing or invalid.", "field": null, "details": null } ], "warnings": null } } } } } }, "403": { "description": "The caller (or the acting user) lacks the `UpdateFeedbackManager` permission, or the plan does not include the Feedback Manager.", "content": { "application/problem+json": { "schema": { "allOf": [ { "$ref": "#/components/schemas/V3ProblemDetails" }, { "type": "object", "properties": { "type": { "enum": [ "https://apidocs.document360.io/apidocs/errors/forbidden" ], "type": "string", "description": "RFC 7807 error type URI. Always `https://apidocs.document360.io/apidocs/errors/forbidden` for 403 responses." }, "status": { "enum": [ 403 ], "type": "integer", "description": "HTTP status code. Always `403` for this response.", "format": "int32" } } } ] }, "examples": { "Insufficient permissions": { "summary": "Insufficient permissions for this resource.", "value": { "type": "https://apidocs.document360.io/apidocs/errors/forbidden", "title": "Forbidden.", "status": 403, "detail": "You do not have permission to perform this action.", "instance": null, "trace_id": "req_abc123def456", "errors": [ { "code": "FORBIDDEN", "message": "Insufficient permissions for this project.", "field": null, "details": null } ], "warnings": null } } } } } }, "404": { "description": "Feedback not found in this project, or it is on a workspace, language, category or article the caller cannot access.", "content": { "application/problem+json": { "schema": { "allOf": [ { "$ref": "#/components/schemas/V3ProblemDetails" }, { "type": "object", "properties": { "type": { "enum": [ "https://apidocs.document360.io/apidocs/errors/resource-not-found" ], "type": "string", "description": "RFC 7807 error type URI. Always `https://apidocs.document360.io/apidocs/errors/resource-not-found` for 404 responses." }, "status": { "enum": [ 404 ], "type": "integer", "description": "HTTP status code. Always `404` for this response.", "format": "int32" } } } ] }, "examples": { "Resource not found": { "summary": "The requested resource does not exist.", "value": { "type": "https://apidocs.document360.io/apidocs/errors/resource-not-found", "title": "Resource not found.", "status": 404, "detail": "The requested resource was not found.", "instance": null, "trace_id": "req_abc123def456", "errors": [ { "code": "RESOURCE_NOT_FOUND", "message": "Resource not found.", "field": null, "details": null } ], "warnings": null } } } } } }, "409": { "description": "The feedback is closed and can no longer be modified (error code `FEEDBACK_CLOSED`).", "content": { "application/problem+json": { "schema": { "allOf": [ { "$ref": "#/components/schemas/V3ProblemDetails" }, { "type": "object", "properties": { "type": { "enum": [ "https://apidocs.document360.io/apidocs/errors/conflict" ], "type": "string", "description": "RFC 7807 error type URI. Always `https://apidocs.document360.io/apidocs/errors/conflict` for 409 responses." }, "status": { "enum": [ 409 ], "type": "integer", "description": "HTTP status code. Always `409` for this response.", "format": "int32" } } } ] }, "examples": { "Feedback is closed": { "summary": "The feedback is already closed. Closed feedback cannot be changed through the API, so this includes repeating the close; it can be reopened only in the portal.", "value": { "type": "https://apidocs.document360.io/apidocs/errors/conflict", "title": "Conflict.", "status": 409, "detail": "This feedback is closed. It can be changed again only after it is reopened in the Document360 portal.", "instance": null, "trace_id": "req_abc123def456", "errors": [ { "code": "FEEDBACK_CLOSED", "message": "Closed feedback cannot be changed through the API. Reopen it in the portal first.", "field": null, "details": null } ], "warnings": null } } } } } }, "422": { "description": "Validation failed (no updatable field, a field this request does not define, invalid or numeric status, a value of the wrong type, a property sent twice, unknown or deactivated assignee, `close` without `status: closed`, or no acting user).", "content": { "application/problem+json": { "schema": { "allOf": [ { "$ref": "#/components/schemas/V3ProblemDetails" }, { "type": "object", "properties": { "type": { "enum": [ "https://apidocs.document360.io/apidocs/errors/validation-error" ], "type": "string", "description": "RFC 7807 error type URI. Always `https://apidocs.document360.io/apidocs/errors/validation-error` for 422 responses." }, "status": { "enum": [ 422 ], "type": "integer", "description": "HTTP status code. Always `422` for this response.", "format": "int32" } } } ] }, "examples": { "Validation failed": { "summary": "One or more request fields failed validation.", "value": { "type": "https://apidocs.document360.io/apidocs/errors/validation-error", "title": "Validation Error", "status": 422, "detail": "One or more fields failed validation.", "instance": null, "trace_id": "req_abc123def456", "errors": [ { "code": "VALIDATION_ERROR", "message": "The field is required.", "field": "name", "details": null } ], "warnings": null } } } } } }, "429": { "description": "Rate limit exceeded. Retry after the duration specified in the Retry-After header.", "headers": { "Retry-After": { "description": "Number of seconds to wait before retrying the request. Use exponential backoff with jitter for optimal retry behavior.", "schema": { "type": "integer", "format": "int32" } }, "X-RateLimit-Limit": { "description": "The maximum number of requests allowed in the current time window for this request's bucket. Read requests (GET/HEAD) and write requests (POST/PUT/PATCH/DELETE) have independent limits, applied per caller (API key or user) per project. Read limits are typically higher than write limits.", "schema": { "type": "integer", "format": "int32" } }, "X-RateLimit-Remaining": { "description": "The number of requests remaining in the current time window. When this reaches 0, subsequent requests will receive a 429 response.", "schema": { "type": "integer", "format": "int32" } }, "X-RateLimit-Reset": { "description": "Number of seconds until the current rate limit window resets.", "schema": { "type": "integer", "format": "int64" } } }, "content": { "application/problem+json": { "schema": { "allOf": [ { "$ref": "#/components/schemas/V3ProblemDetails" }, { "type": "object", "properties": { "type": { "enum": [ "https://apidocs.document360.io/apidocs/errors/too-many-requests" ], "type": "string", "description": "RFC 7807 error type URI. Always `https://apidocs.document360.io/apidocs/errors/too-many-requests` for 429 responses." }, "status": { "enum": [ 429 ], "type": "integer", "description": "HTTP status code. Always `429` for this response.", "format": "int32" } } } ] }, "examples": { "Rate limit exceeded": { "summary": "Rate limit exceeded.", "value": { "type": "https://apidocs.document360.io/apidocs/errors/too-many-requests", "title": "Too Many Requests.", "status": 429, "detail": "Rate limit exceeded. Retry after the duration specified in the Retry-After header.", "instance": null, "trace_id": "req_abc123def456", "errors": [ { "code": "TOO_MANY_REQUESTS", "message": "Rate limit exceeded. Retry after the duration specified in the Retry-After header.", "field": null, "details": null } ], "warnings": null } } } } } }, "500": { "description": "An unexpected server error occurred.", "content": { "application/problem+json": { "schema": { "allOf": [ { "$ref": "#/components/schemas/V3ProblemDetails" }, { "type": "object", "properties": { "type": { "enum": [ "https://apidocs.document360.io/apidocs/errors/internal-server-error" ], "type": "string", "description": "RFC 7807 error type URI. Always `https://apidocs.document360.io/apidocs/errors/internal-server-error` for 500 responses." }, "status": { "enum": [ 500 ], "type": "integer", "description": "HTTP status code. Always `500` for this response.", "format": "int32" } } } ] }, "examples": { "Unexpected server error": { "summary": "Unexpected server error.", "value": { "type": "https://apidocs.document360.io/apidocs/errors/internal-server-error", "title": "Internal Server Error.", "status": 500, "detail": "An unexpected error occurred. Please try again or contact support.", "instance": null, "trace_id": "req_abc123def456", "errors": [ { "code": "INTERNAL_SERVER_ERROR", "message": "An unexpected error occurred.", "field": null, "details": null } ], "warnings": null } } } } } } }, "security": [ { "ApiKey": [] }, { "Bearer": [ "customerApi" ] } ] } } }, "components": { "parameters": { "ProjectId": { "name": "project_id", "in": "path", "description": "The unique identifier of the project. Retrieve project IDs from `GET /v3/projects`.", "required": true, "schema": { "type": "string", "format": "uuid", "example": "9a3b4c5d-6e7f-8a9b-0c1d-2e3f4a5b6c7d" } } }, "schemas": { "UpdateArticleFeedbackRequest": { "type": "object", "properties": { "status": { "allOf": [ { "$ref": "#/components/schemas/V3FeedbackStatus" } ], "description": "New status. `closed` closes the feedback (optionally with `close`); a closed feedback can no\r\nlonger be modified. Matched case-insensitively; a number is refused.", "nullable": true, "example": "inProgress" }, "assignee_id": { "type": "string", "description": "Identifier of the team member to assign the feedback to. Must be an active (not deactivated) user of this\r\nproject. Unassigning is not supported.", "nullable": true, "example": "2b1a0f9e-8d7c-4b6a-9f5e-4d3c2b1a0f9e" }, "close": { "allOf": [ { "$ref": "#/components/schemas/FeedbackCloseRequest" } ], "description": "Close options. Valid only when `status` is `closed`.", "nullable": true }, "user_id": { "type": "string", "description": "Identifier of the team member the change is recorded against in the feedback's history. Required when\r\nthe request is made with an API key or an M2M token without the `X-Acting-User-Id` header; ignored\r\nwhen the token identifies a user.", "nullable": true, "example": "7c1e4d90-2a3b-4c5d-8e9f-0a1b2c3d4e5f" } }, "additionalProperties": false, "description": "Partial update of a feedback record. Every field is optional, but the body must contain at least one of\r\n`status` or `assignee_id`." }, "FeedbackDetailResponseApiResponse": { "required": [ "data", "request_id", "success" ], "type": "object", "properties": { "data": { "allOf": [ { "$ref": "#/components/schemas/FeedbackDetailResponse" } ], "description": "Response data payload." }, "success": { "type": "boolean", "description": "Whether the API request was successful.", "readOnly": true }, "request_id": { "minLength": 1, "type": "string", "description": "Unique identifier for request tracing and correlation.", "readOnly": true }, "errors": { "type": "array", "items": { "$ref": "#/components/schemas/ApiError" }, "description": "List of errors if the request failed.", "nullable": true }, "warnings": { "type": "array", "items": { "$ref": "#/components/schemas/ApiWarning" }, "description": "List of non-fatal warnings from the request.", "nullable": true } }, "additionalProperties": false, "description": "Generic API response wrapper containing typed data." }, "V3ProblemDetails": { "required": [ "status", "title", "type" ], "type": "object", "properties": { "type": { "minLength": 1, "enum": [ "https://apidocs.document360.io/apidocs/errors/bad-request", "https://apidocs.document360.io/apidocs/errors/unauthorized", "https://apidocs.document360.io/apidocs/errors/forbidden", "https://apidocs.document360.io/apidocs/errors/resource-not-found", "https://apidocs.document360.io/apidocs/errors/conflict", "https://apidocs.document360.io/apidocs/errors/validation-error", "https://apidocs.document360.io/apidocs/errors/too-many-requests", "https://apidocs.document360.io/apidocs/errors/internal-server-error" ], "type": "string", "description": "URI reference identifying the error type (links to documentation)." }, "title": { "minLength": 1, "type": "string", "description": "Short human-readable summary of the error type." }, "status": { "enum": [ 400, 401, 403, 404, 409, 422, 429, 500 ], "type": "integer", "description": "HTTP status code.", "format": "int32" }, "detail": { "type": "string", "description": "Human-readable explanation specific to this occurrence.", "nullable": true }, "instance": { "type": "string", "description": "URI of the request that generated the error.", "nullable": true }, "trace_id": { "type": "string", "description": "Request trace identifier for correlation.", "nullable": true }, "errors": { "type": "array", "items": { "$ref": "#/components/schemas/ApiError" }, "description": "Structured list of specific errors (extension field).", "nullable": true }, "warnings": { "type": "array", "items": { "$ref": "#/components/schemas/ApiWarning" }, "description": "Non-fatal warnings (extension field).", "nullable": true } }, "additionalProperties": false, "description": "RFC 7807 Problem Details response for V3 API errors.\r\nContent-Type: application/problem+json" }, "V3FeedbackStatus": { "enum": [ "open", "planned", "inProgress", "complete", "closed" ], "type": "string", "description": "Lifecycle status of a feedback record. A `closed` feedback cannot be changed through the API; it can be\r\nreopened only in the Document360 portal.", "x-enumNames": [ "Open", "Planned", "InProgress", "Complete", "Closed" ], "x-enum-varnames": [ "Open", "Planned", "InProgress", "Complete", "Closed" ], "x-ms-enum": { "name": "V3FeedbackStatus", "modelAsString": true } }, "FeedbackCloseRequest": { "type": "object", "properties": { "comment": { "maxLength": 3000, "type": "string", "description": "Optional resolution note, as plain text. It is stored in the feedback's history and, when the reader is\r\nnotified, included in the email. It is sanitised when stored: HTML markup is removed rather than escaped.", "nullable": true, "example": "Resolved via Jira DOC-123. Updated the setup steps." }, "notify_reader": { "type": "boolean", "description": "Email the reader that the feedback was resolved. Sent only when the reader opted in to updates when\r\nthey left the feedback; otherwise no email is sent. Defaults to `false`.", "nullable": true, "example": true } }, "additionalProperties": false, "description": "Options applied when a PATCH closes a feedback record." }, "FeedbackDetailResponse": { "required": [ "created_at", "discussion_count", "is_page_category", "status", "updated_at" ], "type": "object", "properties": { "feedback_id": { "type": "string", "description": "Unique identifier of the feedback record.", "nullable": true, "readOnly": true, "example": "66f1a2b3-c4d5-4e6f-a7b8-c9d0e1f2a3b4" }, "article_id": { "type": "string", "description": "Identifier of the article the feedback was left on. For page-category feedback\r\n(`is_page_category` = `true`) this is the page category's id. Null only for a legacy record\r\nthat never stored one.", "nullable": true, "readOnly": true, "example": "9a3b4c5d-6e7f-4a9b-8c1d-2e3f4a5b6c7d" }, "article_title": { "type": "string", "description": "Title of the article or page category in the feedback's language. Null when the article has been\r\ndeleted or has no published version in that language.", "nullable": true, "readOnly": true, "example": "Getting started" }, "article_url": { "type": "string", "description": "Public knowledge base URL of the article or page category. Null when it has been deleted or has no published version.", "nullable": true, "readOnly": true, "example": "https://docs.example.com/docs/en/getting-started" }, "workspace_id": { "type": "string", "description": "Identifier of the workspace the feedback belongs to.", "nullable": true, "readOnly": true, "example": "4d3c2b1a-0f9e-4d8c-b7a6-5f4e3d2c1b0a" }, "lang_code": { "type": "string", "description": "Language code of the article version the reader left feedback on.", "nullable": true, "readOnly": true, "example": "en" }, "feedback_type": { "enum": [ "like", "dislike" ], "type": "string", "allOf": [ { "$ref": "#/components/schemas/V3FeedbackType" } ], "description": "Whether the reader liked (`like`) or disliked (`dislike`) the article.", "readOnly": true, "example": "dislike", "x-enumNames": [ "Like", "Dislike" ], "x-enum-varnames": [ "Like", "Dislike" ], "x-ms-enum": { "name": "V3FeedbackType", "modelAsString": true } }, "is_page_category": { "type": "boolean", "description": "Whether the feedback was left on a page category (`true`) rather than an article (`false`).\r\nFor page-category feedback the `article_*` fields describe the page category.", "readOnly": true, "example": false }, "feedback_reasons": { "type": "array", "items": { "type": "string" }, "description": "The reasons the reader picked. Zero or more of `need_more_information`,\r\n`difficult_to_understand`, `inaccurate_or_irrelevant`, `missing_or_broken_link`,\r\n`others` and `comments`. Empty when the reader picked none.", "nullable": true, "readOnly": true, "example": [ "inaccurate_or_irrelevant", "missing_or_broken_link" ] }, "reader_comment": { "type": "string", "description": "The comment the reader wrote with the feedback. Team discussions are separate; read them from\r\n`GET /{feedback_id}/discussions`.", "nullable": true, "readOnly": true, "example": "The setup steps are out of date." }, "status": { "enum": [ "open", "planned", "inProgress", "complete", "closed" ], "type": "string", "allOf": [ { "$ref": "#/components/schemas/V3FeedbackStatus" } ], "description": "Current lifecycle status of the feedback.", "readOnly": true, "example": "inProgress", "x-enumNames": [ "Open", "Planned", "InProgress", "Complete", "Closed" ], "x-enum-varnames": [ "Open", "Planned", "InProgress", "Complete", "Closed" ], "x-ms-enum": { "name": "V3FeedbackStatus", "modelAsString": true } }, "assignee_id": { "type": "string", "description": "Identifier of the team member the feedback is assigned to. Null when unassigned.", "nullable": true, "readOnly": true, "example": "2b1a0f9e-8d7c-4b6a-9f5e-4d3c2b1a0f9e" }, "created_at": { "type": "string", "description": "When the reader submitted the feedback (UTC).", "format": "date-time", "readOnly": true, "example": "2026-10-10T08:15:00Z" }, "updated_at": { "type": "string", "description": "When the feedback last changed (UTC): the latest status change, assignment, close, note or team\r\ndiscussion, or `created_at` when nothing has changed since it was submitted.", "format": "date-time", "readOnly": true, "example": "2026-10-12T11:02:00Z" }, "discussion_count": { "type": "integer", "description": "Number of team discussion entries on the feedback, including the notes added in the Portal. Call `GET /{feedback_id}/discussions` only when it is above 0.", "format": "int32", "readOnly": true, "example": 2 } }, "additionalProperties": false, "description": "One feedback record, as returned by `GET /{feedback_id}` and `PATCH /{feedback_id}`: the same fields as\r\na list row. Team discussions are read from `GET /{feedback_id}/discussions`; the reader's name and email are\r\nnot returned by any endpoint." }, "ApiError": { "required": [ "code", "message" ], "type": "object", "properties": { "code": { "minLength": 1, "enum": [ "ACCESS_DENIED", "ARCHIVED_CONTENT_READ_ONLY", "ARCHIVE_ALREADY_ARCHIVED", "ARCHIVE_NOT_ARCHIVED", "BAD_REQUEST", "CONFLICT", "FEATURE_NOT_IN_LICENSE", "FEEDBACK_CLOSED", "FORBIDDEN", "INTERNAL_SERVER_ERROR", "LICENSE_LIMIT_EXCEEDED", "OPERATION_FAILED", "PERMISSION_DENIED", "PREMIUM_FEATURE_NOT_IN_LICENSE", "RESOURCE_NOT_FOUND", "TOO_MANY_REQUESTS", "UNAUTHORIZED", "UNRECOGNIZED_FIELD", "UNRECOGNIZED_FIELDS", "VALIDATION_ERROR" ], "type": "string", "description": "Machine-readable error code (e.g. VALIDATION_ERROR, RESOURCE_NOT_FOUND)." }, "message": { "minLength": 1, "type": "string", "description": "Human-readable error message." }, "field": { "type": "string", "description": "The request field that caused the error, if applicable.", "nullable": true }, "details": { "type": "string", "description": "Additional context about the error.", "nullable": true } }, "additionalProperties": false, "description": "Represents an error returned by the API." }, "ApiWarning": { "required": [ "code", "message" ], "type": "object", "properties": { "code": { "minLength": 1, "type": "string", "description": "Machine-readable warning code." }, "message": { "minLength": 1, "type": "string", "description": "Human-readable warning message." } }, "additionalProperties": false, "description": "Represents a non-fatal warning from the API." }, "V3FeedbackType": { "enum": [ "like", "dislike" ], "type": "string", "description": "Whether the reader liked (`like`) or disliked (`dislike`) the article, as on the knowledge base's\r\nlike / dislike buttons.", "x-enumNames": [ "Like", "Dislike" ], "x-enum-varnames": [ "Like", "Dislike" ], "x-ms-enum": { "name": "V3FeedbackType", "modelAsString": true } } }, "securitySchemes": { "ApiKey": { "type": "apiKey", "description": "API key for machine-to-machine integrations, webhooks, and CI/CD (recommended). This is a static, pre-shared secret - treat it as an opaque string and do not parse it; it is an API key, not an OAuth 2.0 access token. Create one in the portal under **Settings > Knowledge base portal > API keys** using the **Create API key** button - this is a different credential from the V1/V2 *API token*, which lives on its own screen and will not authenticate a V3 request. The plaintext key (format `d360_sk_...`) is shown only once, at creation. Send it in the `X-API-Key` header: `X-API-Key: d360_sk_...`. Each key carries a fixed portal role, content role, and content-access scope, supports an optional expiry, and can be disabled or deleted at any time from the portal.", "name": "X-API-Key", "in": "header" }, "Bearer": { "type": "oauth2", "description": "All V3 endpoints require a Bearer token. Generate tokens in the Document360 portal under **Settings > API Tokens**. Tokens are project-scoped, require the `customerApi` scope, and do not expire by default. Tokens can be revoked at any time from the portal. Include the token in every request: `Authorization: Bearer `. Alternatively, use the Authorize button below to sign in via OAuth2 Authorization Code flow with PKCE.", "flows": { "authorizationCode": { "authorizationUrl": "https://identity.document360.io/connect/authorize", "tokenUrl": "https://identity.document360.io/connect/token", "scopes": { "openid": "OpenID Connect", "profile": "User profile", "email": "User email", "customerApi": "Document360 Customer API" }, "x-usePkce": { "disableManualConfiguration": true, "hideClientSecretInput": true } } }, "x-d360-clientId": "apiHubWebClient" } } } } ````